乐趣区

编码1蜜蜂采蜜

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

Flower open
Bee 1's eating time!
Bee 2's eating time!
Bee 3's eating time!
Floer close
Bee 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()
退出移动版