1. 什么是观察者模式
就是在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新
2. 观察者模式包含的角色
2.1. Observer(抽象观察者角色)
为所有的具体观察者定义一个接口,在得到主题通知时更新自己
2.2. Subject(抽象被观察者角色(主题))
也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。它提供了一系列方法来增加和删除观察者对象,同时也定义了通知方法notify()。可以是接口,也可以是抽象类或者具体类。
2.3. ConcreteObserver(具体观察者角色)
在具体观察者中维护了一个指向具体被观察者对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的update()方法。通常在实现时,可以调用具体被观察者类的方法将自己添加到Subject类的集合中或者从中删除
2.4. ConcreteSubject(具体被观察者角色)
Subject类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知。
3. 类图
image.png4. 代码实现
4.1. 抽象观察者
public abstract class Observer {
public abstract void update(String newState);
}
4.2. 抽象被观察者
public abstract class Subject {
private List<Observer> observers=new ArrayList<Observer>();
//增加观察者
public void attach (Observer observer){
observers.add(observer);
}
//移除观察者
public void remove(Observer observer){
observers.remove(observer);
}
//如果有新消息通知观察者
public void notifyObservers(String newState){
for (Observer o : observers) {
o.update(newState);
}
}
}
4.3. 具体观察者
public class ConcreteObserver extends Observer {
private String name;
private String state;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String newState) {
this.state = newState;
read(state);
}
public void read(String state) {
System.out.println(name + "接收到了新状态:" + state);
}
}
4.4. 具体被观察者
public class ConcreteSubject extends Subject{
private String state;
public String getState() {
return state;
}
public void change(String newState) {
state = newState;
//状态发生改变,通知观察者
notifyObservers(state);
}
}
4.5. 测试类
public class Test {
public static void main(String[] args) {
ConcreteObserver lisi = new ConcreteObserver("lisi");
ConcreteObserver zhangsan = new ConcreteObserver("zhangsan");
ConcreteObserver wangwu = new ConcreteObserver("wangwu");
ConcreteSubject subject = new ConcreteSubject();
subject.attach(lisi);
subject.attach(wangwu);
subject.attach(zhangsan);
subject.change("11点了");
subject.remove(wangwu);
subject.change("12点了");
}
}
运行结果
lisi接收到了新状态:11点了
wangwu接收到了新状态:11点了
zhangsan接收到了新状态:11点了
lisi接收到了新状态:12点了
zhangsan接收到了新状态:12点了
5. 观察者模式适用场景
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使他们可以独立地改变和复用
- 一个对象的改变将导致一个或多个其他对象也发生改变,并不知道具体有多少对象将发生改变,也不知道这些对象是谁
- 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象...,可以使用观察者模式创建一种链式触发机制。
网友评论