【Coding】【6】观察者实现:蜜蜂采蜜

本文最后更新于:2021年12月22日 上午

【Coding】系列目录


用代码实现以下输出

一朵花有Open和Close两种状态,3只蜜蜂在花Open的时候去采蜜,在花Close的时候回巢,用面向对象技术和Design Pattern方法模拟上面过程,输出如下:

1
2
3
4
5
6
7
8
Flower open
Bee 1's eating time!
Bee 2's eating time!
Bee 3's eating time!
Flower close
Bee 1's bed time!
Bee 2's bed time!
Bee 3's bed time!

编码实现上述情景,要求使用一种Design Pattern方法,使花和蜜蜂之间松耦合。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

protocol ObserverProtocol {
var id: Int {get set}
func onValueChanged(_ value: Any?)
}

protocol ObservableProtocol: class {
var observers: [ObserverProtocol] {get set}
func addObserver(_ observer: ObserverProtocol)
func removeObserver(_ observer: ObserverProtocol)
func notifyObservers(_ observers: [ObserverProtocol])
}

class Observable<T>: ObservableProtocol {
var value: T {
didSet {
self.notifyObservers(self.observers)
}
}

internal var observers: [ObserverProtocol] = []

init(value: T) {
self.value = value
}

func addObserver(_ observer: ObserverProtocol) {
guard self.observers.contains(where: { $0.id == observer.id}) == false else {
return
}
self.observers.append(observer)
}

func removeObserver(_ observer: ObserverProtocol) {
guard let index = self.observers.firstIndex(where: { $0.id == observer.id}) else {
return
}
self.observers.remove(at: index)
}

func notifyObservers(_ observers: [ObserverProtocol]) {
observers.forEach({$0.onValueChanged(value)})
}

deinit {
observers.removeAll()
}
}


enum FlowerStatus: String {
case open = "Flower open"
case close = "Flower close"
}

class Flower: Observable<FlowerStatus> {
var status: FlowerStatus {
get {
return self.value
}
set {
print(newValue.rawValue)
self.value = newValue
}
}
}

struct Bee: ObserverProtocol {
var id: Int
var name: String
func onValueChanged(_ value: Any?) {
if let status = value as? FlowerStatus {
if status == .open {
print("\(name)'s eating time!")
} else {
print("\(name)'s beding time!")
}
}
}
}

func beeTime() {
let flower = Flower(value: .close)
let bee1 = Bee.init(id: 1, name: "Bee 1")
let bee2 = Bee.init(id: 2, name: "Bee 2")
let bee3 = Bee.init(id: 3, name: "Bee 3")
flower.addObserver(bee1)
flower.addObserver(bee2)
flower.addObserver(bee3)

flower.status = .open
flower.status = .close
}

beeTime()

Observable另一种实现,注意,这种方法实现,打印是无序的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Observable<T> {
typealias CompletionHandler = ((T) -> Void)

var value: T {
didSet {
self.notifyObservers(self.observers)
}
}

var observers: [Int: CompletionHandler] = [:]

init(value: T) {
self.value = value
}

func addObserver(_ observer: ObserverProtocol, completion: @escaping CompletionHandler) {
self.observers[observer.id] = completion
}

func removeObserver(_ observer: ObserverProtocol) {
self.observers.removeValue(forKey: observer.id)
}

func notifyObservers(_ observer: [Int: CompletionHandler]) {
observers.forEach({$0.value(value)})
}

deinit {
observers.removeAll()
}
}

func beeTime() {
let flower = Flower(value: .close)

let bee1 = Bee.init(id: 1, name: "Bee 1")
let bee2 = Bee.init(id: 2, name: "Bee 2")
let bee3 = Bee.init(id: 3, name: "Bee 3")
flower.addObserver(bee1) { (status) in
if status == .open {
print("\(bee1.name)'s eating time!")
} else {
print("\(bee1.name)'s beding time!")
}
}

flower.addObserver(bee2) { (status) in
if status == .open {
print("\(bee2.name)'s eating time!")
} else {
print("\(bee2.name)'s beding time!")
}
}

flower.addObserver(bee3) { (status) in
if status == .open {
print("\(bee3.name)'s eating time!")
} else {
print("\(bee3.name)'s beding time!")
}
}

flower.status = .open
flower.status = .close
}

beeTime()


联系方式

邮箱: adrenine@163.com