设计模式 ~ 观察者模式

  • 定义:观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
  • 角色
    • Subject:抽象被观察者,定义增加和删除观察者的抽象方法以及通知观察者状态改变的方法
    • ConcreateSubject:具体被观察者,实现Subject,,内部存储观察者列表,通知时遍历观察者更新
    • Observer:抽象观察者,定义观察者收到通知的内容的抽象方法
    • ConcreteObserver:具体观察者,实现抽象观察者,重新更新方法做出相应处理
  • 代码实现
    • 1、实现抽象观察者Observer
/**
 * 观察者的接口
 *
 * @author LTP  2021/11/10
 */
interface Observer {

    /**
     * 定义一个收到被观察者改变而更新的动作
     *
     * @param msg 收到的消息
     */
    fun update(msg: String)
}
  • 2、实现具体观察者
/**
 * 具体观察者
 * @author LTP  2021/11/10
 */
class ConcreteObserver(private val name: String) : Observer {

    override fun update(msg: String) {
        println("${name}被通知:$msg")
    }
}
  • 3、实现抽象被观察者
/**
 * 定义被观察者接口
 * @author LTP  2021/11/10
 */
interface Subject {

    /**
     * 绑定观察者
     * @param observer 观察者
     */
    fun attach(observer: Observer)

    /**
     * 解绑观察者
     * @param observer 观察者
     */
    fun detach(observer: Observer)

    /**
     * 通知观察者
     * @param msg 通知的内容
     */
    fun notify(msg: String)
}
  • 4、实现具体被观察者
/**
 * 具体被观察者
 *
 * @author LTP  2021/11/10
 */
class ConcreteSubject : Subject {
    /** 存储绑定的观察者 */
    private val mObserverList = ArrayList()

    override fun attach(observer: Observer) {
        mObserverList.add(observer)
    }

    override fun detach(observer: Observer) {
        mObserverList.remove(observer)
    }

    override fun notify(msg: String) {
        // 循环遍历观察者逐个通知
        mObserverList.forEach { observer -> observer.update(msg) }
    }
}
  • 5、具体调用
/**
 * 调用类
 *
 * @author LTP  2021/11/10
 */
class Main {

    companion object {
        @JvmStatic
        fun main(args: Array) {
            val subject = ConcreteSubject()

            val observer1 = ConcreteObserver("观察者1")
            val observer2 = ConcreteObserver("观察者2")
            val observer3 = ConcreteObserver("观察者3")

            subject.attach(observer1)
            subject.attach(observer2)
            subject.attach(observer3)

            subject.notify("我要更新啦")

            subject.detach(observer2)
            subject.notify("我删掉观察者2再更新一次")
        }
    }
}
运行结果:
  观察者1被通知:我要更新啦
  观察者2被通知:我要更新啦
  观察者3被通知:我要更新啦
  观察者1被通知:我删掉观察者2再更新一次
  观察者3被通知:我删掉观察者2再更新一次
  • 应用场景以及优缺点
    • 应用场景:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。(如Android中的EventBus、广播、LiveData)
    • 优点:1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
    • 缺点:在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。

你可能感兴趣的:(设计模式 ~ 观察者模式)