定义
定义对象间的一种一对多的一种依赖关系,当一个对象的状态发生改变时,所有依赖于他的对象都能得到通知并被自动更新。
本质
触发联动
登场角色
-
Subject(观察对象)
被观察对象接口或者抽象类
-
ConcreteSubject(具体的观察对象)
具体的被观察对象
-
Observer(观察者)
负责接收来自观察对象的状态变化的通知
-
ConcreteObserve(具体的观察者)
具体的观察者,实现观察者角色所定义的接口。
示例代码
/**
* 观察者
*/
public class Coder implements Observer {
String name;
public Coder(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
System.out.println("Hi, " + name + " DevTechFrontier更新了" + arg);
}
@Override
public String toString() {
return "Coder{" +
"name='" + name + '\'' +
'}';
}
}
/**
* 被观察者
*/
public class DevTechFronter extends Observable {
public void postNewContent(String content){
//标志内容发生改变
setChanged();
//通知所有观察者
notifyObservers(content);
}
}
public class Client {
public static void main(String[] args){
//被观察的角色
DevTechFronter devTechFronter = new DevTechFronter();
//观察者
Coder coder1 = new Coder("Coder1");
Coder coder2 = new Coder("Coder2");
Coder coder3 = new Coder("Coder3");
//将观察者注册到被观察者列表中
devTechFronter.addObserver(coder1);
devTechFronter.addObserver(coder2);
devTechFronter.addObserver(coder3);
//发布消息
devTechFronter.postNewContent("this is the new content.");
}
}
运行结果
Hi, Coder3 DevTechFrontier更新了this is the new content.
Hi, Coder2 DevTechFrontier更新了this is the new content.
Hi, Coder1 DevTechFrontier更新了this is the new content.
优点
- 观察者模式实现了观察者和目标之间的抽象耦合,原本目标对象发生变化时,需要直接调用所有的观察者对象,但是抽象出观察者接口后,目标和观察者就在抽象层面上耦合和,也就是目标只知道观察者接口,并不知道具体的观察者的类,从而实现了目标类和观察者之前的耦合。
- 观察者模式实现了动态联动。所谓联动,就是一个操作会引起其他相关的操作。
缺点
- 可能会引起无谓的操作。 由于观察者模式每次都是广播通信,不管观察者是否需要,每个观察者都会被调用update方法。
使用场景
- 当一个抽象模型有两个方面,一个方面的操作依赖于另一个方面的状态变化时,就可以选用观察者模式,将这两种封装成观察者和目标对象。
- 如果在更改一个对象的时候,同时需要连带改变其他的对象。
- 当一个对象必须通知其他对象,但是又希望这个对象和其他被通知的对象松散耦合的时候。
网友评论