二十八、观察者模式

1. 何为观察者模式

观察者模式也叫做发布-订阅模式。如它的别名暗示的那样,它很像杂志的订阅。当从杂志发行商订阅杂志的时候,读者把名字和邮寄地址提供给发行商,这样新的一期就能送到读者手上了。发行商保证把正确的杂志发送到正确的地址,一般来说,读者不会收到他没有订阅的杂志。这正是订阅者模式的工作方式。

观察者通过通知器(发行商)把自己注册到(订阅)特定的通知(杂志)。当有通知的时候,观察者只从通知器得到它订阅的通知。

观察者模式的类图

Observer从Subject订阅通知,ConcreteObserver实现抽象Observer并重载其update犯法。一旦Subject的实例需要通知Observer任何新的变更,Subject会发送update消息来通知存储在内部列表中所有注册的Observer。在ConcreteObserver的update方法的实际实现中,Subject的内部状态可被取得并在以后进行处理。

观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都的到通知并被自动更新。

在观察者模式里,一个对象在状态变化的时候会通知另一个对象。参与者并不需要知道其他对象的具体是干什么的 - 这是一种降低耦合度的设计。这个设计模式常用于在某个属性改变的时候通知关注该属性的对象。

常见的使用方法是观察者注册监听,然后再状态改变的时候,所有观察者们都会收到通知。

Cocoa 使用两种方式实现了观察者模式: NotificationKey-Value Observing (KVO)

2. 通知-Notification 和 键值观察-KVO

这里所讲的通知是基于订阅-发布模式的,即一个对象(发布者)向其他对象(订阅者)发送消息。发布者永远不需要知道订阅者的任何数据。

Apple对于通知的使用很频繁,比如当键盘弹出或者收起的时候,系统会分别发送UIKeyboardWillShowNotification/UIKeyboardWillHideNotification 的通知。当你的应用切到后台的时候,又会发送 UIApplicationDidEnterBackgroundNotification 的通知。

  • 注意:打开 UIApplication.swift 文件,在文件结尾你会看到二十多种系统发送的通知。

在 KVO 里,对象可以注册监听任何属性的变化,不管它是否持有。如果感兴趣的话,可以读一读苹果 KVO 编程指南

3. 代码实现

import Foundation

class Observer {
    func updateData(data: String) {}
}

class CourseObserver: Observer {
    override func updateData(data: String) {
        print("课程更新了---\(data)")
    }
}

class StudyObserver: Observer {
    override func updateData(data: String) {
        print("学习更新了---\(data)")
    }
}

class ObserverCenter {
    var observerMap: [String: Observer] = [:]
    
    func addObserver(observerName: String, observer: Observer) {
        observerMap[observerName] = observer
    }
    
    func deleteObserver(observerName: String) {
        observerMap.removeValue(forKey: observerName)
    }
    
    func notifyObserver(data: String) {
        for (_, value) in observerMap {
            let observer: Observer = value
            observer.updateData(data: data)
        }
    }
}

let observerCenter: ObserverCenter = ObserverCenter()

let courseObserver: CourseObserver = CourseObserver()
observerCenter.addObserver(observerName: "Course", observer: courseObserver)

let studentObserver: StudyObserver = StudyObserver()
observerCenter.addObserver(observerName: "Student", observer: studentObserver)

observerCenter.notifyObserver(data: "FlyElephant")
测试结果
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容