定义
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,所有依赖与他的状态都会被通知到。
使用场景
Subject 抽象的主题,也就是被观察者的角色,抽象主题角色把所有观察者对象的引用存在一个集合中,每个主题都可以有任意数量的观察者,抽象主题提供接口,可以增加删除观察者对象。
ConcreteSubject 具体,该角色将有关状态存在具体观察者对象,具体内部发生变化的时候,给所有注册过的通知者发出通知,具体主题角色又叫做具体被观察者
Observer 抽象观察者,该角色是观察者的抽象类,它定义了一个更新接口,使得在得到主题的更改通知的时候更新自己
ConCreteObserver 具体的观察者,该角色实现抽象观察者实现的接口,以便在主题变化的时候更新自身状态
UML图
代码案例
最简单的例子
public class Coder implements Observer {
private String name;
public Coder(String name){
this.name=name;
}
@Override
public void update(Observable o, Object arg) {
System.out.println("收到通知");
}
}
public class DevTechFrontier extends Observable {
public void postNewTouchPublication(String content) {
setChanged();
notifyObservers();
}
}
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
val devTechFrontier = DevTechFrontier()
val coder = Coder("coder1")
devTechFrontier.addObserver(coder)
devTechFrontier.postNewTouchPublication("新的技术周刊发布")
}
}
常用的例子
因为Observable和Observer 是内嵌入JDK中的所以可以直接可以用到,后续一般情况下可以比如Observer 这个接口放在 Observable的一个map或者list之中,在需要通知的时候遍历这个集合回调即可,当然 需要给出的是一个注册和取消注册的方法。
interface WeatherObserver {
void notifyWeather();
}
public class BeiJingWeather implements WeatherObserver {
@Override
public void notifyWeather() {
System.out.println("notifyWeather:这里是北京,收到通知 ");
}
}
public class GuangDongWeather implements WeatherObserver {
@Override
public void notifyWeather() {
System.out.println("notifyWeather:这里是广东,收到通知 ");
}
}
package com.example.leak.observer;
import java.util.List;
public class WeatherObservable {
private List<WeatherObserver> list;
public void resiter(WeatherObserver observer) {
list.add(observer);
}
public void unresiter(WeatherObserver observer) {
list.remove(observer);
}
public void notifyAllWeather() {
for (int i = 0; i <list.size() ; i++) {
list.get(i).notifyWeather();
}
}
}
这种自己实现的观察者模式才是比较常见能解耦两个模块
优缺点
1.观察者模式和被观察者之间是抽象耦合,应对业务变化
2.增强系统灵活性,可扩展性
缺点
在应用观察者模式时,需要考虑一下开发效率和运行效率问题