观察者模式

25 年 11 月 22 日 星期六
862 字
5 分钟

什么是观察者模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

Redux是观察者模式的集大成者,在GitHub拥有57.8k的收藏

观察者模式的实现需要三个角色进行搭配完成,其分别为:

  1. Subject
  2. Observer
  3. Client

Subject的定义:

Subject类也叫抽象类,可以理解成一个实现目的的工具函数集合,他在整个模式中起到的作用一般包括:

  • 增加
  • 删除
  • 修改
  • 读取

当我们对这里的函数进行调用后,函数完成我们需要的操作,并对**Observer**发出通知。

样例:

  • ObserverManager.kt
plain
interface ObserverListener {
    // 刷新操作
    fun observerUpData(count: String)
}

在观察者模式下,真正的信息存放在一个私有变量中,我们不能通过直接对这个变量进行操作来修改其值,只能通过我们事先定义好的函数对其进行操作,这很大程度上保证了变量的安全性,降低了值被错误修改的可能性。

Observer的定义:

Observer是一个抽象类或者接口,当数据被更新时,Observer可以对实现了数据观察的每个Client进行通知。

样例:

  • ObserverManager.java
plain
class ObserverManager : SubjectListener {
    companion object {
        val instance: ObserverManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            ObserverManager()
        }
    }

    //观察者集合
    private val list = ArrayList<ObserverListener>()
    override fun add(observerListener: ObserverListener) {
        // 加入队列
        list.add(observerListener)
    }

    override fun notifyObserver(count: String) {
        // 通知观察者刷新数据
        for (observerListener in list) {
            observerListener.observerUpData(count)
        }
    }

    override fun remove(observerListener: ObserverListener) {
        // 从监听队列删除
        list.remove(observerListener)
    }
}

//被观察者接口
interface SubjectListener {
    // 添加监听
    fun add(observerListener: ObserverListener)

    // 通知的内容
    fun notifyObserver(count: String)

    // 删除
    fun remove(observerListener: ObserverListener)
}

以上例子表示当被观察的变量发生数据更新时,Observer将对每个实现了监听的Client进行播报,在注释处可以根据更新后的数据完成某些操作。

Client的定义

相较于前两个角色的定义,Client就很好理解了,即我们接收Observer信息的角色,也就是我们这套系统最终服务的对象。

Kotlin样例:

  • MainActivity.kt
kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // 注册观察者
    ObserverManager.instance.add(this)

    val intent= Intent(this@MainActivity,MainActivity2::class.java)
    startActivity(intent)
}

override fun observerUpData(count: String) {
    Log.e("111","=监听到==》$count")
}

override fun onDestroy() {
    super.onDestroy()
    ObserverManager.instance.remove(this)
}
  • MainActivity2.kt
plain
fun bt_click(view: View) {

    // 传输数据到第一个页面
    ObserverManager.instance.notifyObserver("我是第二页面的数据,触发更新数据啦!!!")
}

总结:

灵活运用观察者模式可以对整个App的所有必要数据进行中心化管理,譬如用户信息、会员状态、设置信息、语言版本、应用主题等需要全剧应用的数据,可以极大程度节省我们在数据管理方面所投入的成本。

观察者模式所带来的中心化数据管理模式带来的优势并不仅限于节省我们的时间时间成本,也有助于我们在debug时清晰的看到任何时间下的数据动态,有助于我们分析查错。

但需要注意的是,任何View作为Client时,如果界面被隐藏或销毁,需要在这之前将监听关闭,否则可能会导致空指针异常,我不清楚这在Android是否适用,但在iOS端,这个问题是致命的。

文章标题:观察者模式

文章作者:Aridvian

文章链接:https://blog.aridvian.top/posts/kt-observer[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。