观察者模式(Observer Pattern)
定义:定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
认识观察者模式:我们就拿报纸的订阅为例。
- 报社(Subject)的业务就是出版报纸。
- 向报社订阅报纸,只要他们有新报纸出版,就会给订阅的人(Observer)送去。
- 当订阅的人(Observer)不想在看报纸时,可以取消订阅,报社(Subject)就不会再送报纸。
- 只要报社(Subject)还在运营,就会有人去订阅或取消报纸。
报社 + 订阅者 = 观察者模式
Subject(主题):负责给已经注册观察者发送新消息。
Observer(观察者):向 Subject 进行注册后,可收到新信息。
摘自《HeadFirst设计模式》
意义:当两个对象之间松耦合,它们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主题和观察者之间松耦合。
具体代码实现:假设实现广播功能,广播台就是实现 Subject 的实体,听众就是观察者
Sbuject.java: 给广播台实现用
public interface Subject {
//以下两个方法都需要传入一个观察者作为变量,该观察者用于注册和删除
public void registerObserver(Observer o);
public void removeObserver(Observer o);
//当主题有新消息,调用这个来通知观察者们
public void notifyObservers();
}
Observer.java:给听众(观察者)实现,实现消息更新
public interface Observer {
public void update(String message);
}
DisplayElement.java:显示新消息功能
public interface DisplayElement {
public void display();
}
BroadCast.java:广播台
public class Broadcast implements Subject{
private String message;
private List<Observer> observerList;//观察者列表,用于保存对实现了 Observer 接口实现类的引用
public Broadcast() {
observerList = new ArrayList<>();
}
@Override
public void registerObserver(Observer o) {
observerList.add(o);//注册观察者
}
@Override
public void removeObserver(Observer o) {
observerList.remove(o);//移除观察者
}
@Override
//通知观察者
public void notifyObservers() {
for(Observer o : observerList){
o.update(message);//调用观察者的 update 方法更新观察者的信息
}
}
//消息有更新是调用
public void haveNewMessage(){
notifyObservers();
}
//更新消息
public void setNewMessage(String message){
this.message = message;
haveNewMessage();
}
}
ObserverA.java:实现类观察者接口的观察者
public class ObserverA implements Observer,DisplayElement {
private Subject broadcast;//对广播台的引用
private String message;
public ObserverA(Subject broadcast) {
this.broadcast = broadcast;//创建观察者是传入广播台
broadcast.registerObserver(this);//向广播台进行注册
}
@Override
public void display() {
System.out.println("I'm observerA,I recieve a new message: " + message );
}
@Override
public void update(String message) {
this.message = message;//更新消息
display();//展示消息
}
}
测试:
@Test
public void test(){
Broadcast broadcast = new Broadcast();
ObserverA observerA = new ObserverA(broadcast);//创建观察者A并向广播台注册
ObserverB observerB = new ObserverB(broadcast);//同理
//更新广播台消息
broadcast.setNewMessage("hello");
broadcast.setNewMessage("a");
broadcast.setNewMessage("b");
broadcast.setNewMessage("c");
}
测试结果:
I’m observerA,I recieve a new message: hello
I’m observerB,I recieve a new message: hello
I’m observerA,I recieve a new message: a
I’m observerB,I recieve a new message: a
I’m observerA,I recieve a new message: b
I’m observerB,I recieve a new message: b
I’m observerA,I recieve a new message: c
I’m observerB,I recieve a new message: c