-
定义:观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
-
角色:
- Subject:抽象被观察者,定义增加和删除观察者的抽象方法以及通知观察者状态改变的方法
- ConcreateSubject:具体被观察者,实现Subject,,内部存储观察者列表,通知时遍历观察者更新
- Observer:抽象观察者,定义观察者收到通知的内容的抽象方法
- ConcreteObserver:具体观察者,实现抽象观察者,重新更新方法做出相应处理
-
代码实现
/**
* 观察者的接口
*
* @author LTP 2021/11/10
*/
interface Observer {
/**
* 定义一个收到被观察者改变而更新的动作
*
* @param msg 收到的消息
*/
fun update(msg: String)
}
/**
* 具体观察者
* @author LTP 2021/11/10
*/
class ConcreteObserver(private val name: String) : Observer {
override fun update(msg: String) {
println("${name}被通知:$msg")
}
}
/**
* 定义被观察者接口
* @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)
}
/**
* 具体被观察者
*
* @author LTP 2021/11/10
*/
class ConcreteSubject : Subject {
/** 存储绑定的观察者 */
private val mObserverList = ArrayList<Observer>()
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) }
}
}
/**
* 调用类
*
* @author LTP 2021/11/10
*/
class Main {
companion object {
@JvmStatic
fun main(args: Array<String>) {
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中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。
网友评论