一句话总结
定义了一种一对多的依赖关系,让多个观察对象同时观察同一个主题对象。当这个主题对象状态发生改变时,会通知所有观察对象,是它们能够自动更新自己,
需求
最近股市比较火,公司的员工都想抽空就看一下股市行情,但又怕被老板发现,就跟前台的小美搞好关系。当老板回来的时候,让小美打内部电话通知大家一下。
Code V1.0
双向耦合的代码
func main() {
let secretary = Secretary()
let colleague1 = StockObserve(name: "同事1", sub: secretary)
let colleague2 = StockObserve(name: "同事2", sub: secretary)
secretary.attach(observe: colleague1)
secretary.attach(observe: colleague2)
secretary.action = "老板回来了"
secretary.notify()
}
class Secretary {
var observes: [StockObserve] = []
var action = ""
func attach(observe: StockObserve) {
observes.append(observe)
}
func notify() {
observes.forEach { (item) in
item.update()
}
}
}
class StockObserve {
let name: String
let sub: Secretary
init(name: String, sub: Secretary) {
self.name = name
self.sub = sub
}
func update() {
print("\(sub.action), \(name) 关闭股票行情,继续工作")
}
}
Code V2.0
观察者模式实现
static func main() {
let boss = Boss(subjectState: "老板回来了")
let lookStockColleague = StockObserve(name: "小明", sub: boss)
let lookNBAColleague = NBAObserve(name: "小方", sub: boss)
boss.attach(observe: lookStockColleague)
boss.attach(observe: lookNBAColleague)
boss.notify()
}
protocol Subject {
var observes: [Observe] { get set }
var subjectState: String { get set }
func attach(observe: Observe)
func detach(observe: Observe)
func notify()
}
protocol Observe {
var name: String { get set }
var sub: Subject { get set }
func update()
}
class Boss: Subject {
var observes: [Observe]
var subjectState: String
init(subjectState: String) {
observes = []
self.subjectState = subjectState
}
func attach(observe: Observe) {
observes.append(observe)
}
func detach(observe: Observe) {
observes.removeAll { (item) -> Bool in
item.name == observe.name
}
}
func notify() {
observes.forEach { (item) in
item.update()
}
}
}
//秘书类同Boss类
class Secretary: Subject {
var observes: [Observe]
var subjectState: String
init(subjectState: String) {
observes = []
self.subjectState = subjectState
}
func attach(observe: Observe) {
observes.append(observe)
}
func detach(observe: Observe) {
observes.removeAll { (item) -> Bool in
item.name == observe.name
}
}
func notify() {
observes.forEach { (item) in
item.update()
}
}
}
class StockObserve: Observe {
var name: String
var sub: Subject
init(name: String, sub: Subject) {
self.name = name
self.sub = sub
}
func update() {
print("\(sub.subjectState), \(name)关闭股票行情,继续工作")
}
}
class NBAObserve: Observe {
var name: String
var sub: Subject
init(name: String, sub: Subject) {
self.name = name
self.sub = sub
}
func update() {
print("\(sub.subjectState), \(name)关闭NBA直播,继续工作")
}
}
适用场景
当一个对象更改时,需要同时更改另外一个或者多个对象时,使用观察者模式比较合适。