一朵花有Open和Close两种状态,3只蜜蜂在花Open的时候去采蜜,在花Close的时候回巢,用面向对象技术和Design Pattern方法模拟上面过程,输出如下:
Flower openBee 1's eating time!Bee 2's eating time!Bee 3's eating time!Floer closeBee 1's bed time!Bee 2's bed time!Bee 3's bed time!
编码实现上述情景,要求使用一种Design Pattern方法,使花和蜜蜂之间松耦合。
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
另一种实现,注意,这种方法实现,打印是无序的
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()