观察者模式也叫作发布-订阅模式,也就是事件监听机制。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
观察者模式的组成如下:
抽象主题
抽象主题角色把所有对观察者对象的引用保存在一个聚集中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
具体主题
将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记过的观察者发出通知。
抽象观察者
为所有的具体观察者提供一个接口,在得到主题通知时更新自己
具体观察者
存储与主题的状态相关的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态协调
具体实现如下
抽象主题
package observer;
import java.util.ArrayList;
import java.util.List;
/**
* Created by canon on 2018/12/3.
*/
public abstract class Subject {
private List<Observer> observers = new ArrayList<>();
//增加观察者
public void attach(Observer observer){
observers.add(observer);
}
//解除观察者
public void detach(Observer observer){
observers.remove(observer);
}
//将状态通知给所有的观察者
public void notifyAllObservers(){
for (Observer observer : observers) {
observer.update();
}
}
}
具体主题
package observer;
/**
* Created by canon on 2018/12/3.
*/
public class ConcreteSubject extends Subject {
private String status;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
抽象观察者
package observer;
/**
* Created by canon on 2018/12/3.
*/
public abstract class Observer {
public abstract void update();
}
具体观察者
package observer;
/**
* Created by canon on 2018/12/3.
*/
public class ConcreteObserver extends Observer {
private String status;
private ConcreteSubject subject;
private String name;
public ConcreteObserver(ConcreteSubject subject, String name) {
this.name = name;
this.subject = subject;
}
@Override
public void update() {
this.status = subject.getStatus();
System.out.println(this.name+"状态改变:"+status);
}
public ConcreteSubject getSubject() {
return subject;
}
public void setSubject(ConcreteSubject subject) {
this.subject = subject;
}
}
客户端调用
package observer;
/**
* Created by canon on 2018/12/3.
*/
public class Controller {
public static void main(String[] args) {
ConcreteSubject concreteSubject = new ConcreteSubject();
concreteSubject.attach(new ConcreteObserver(concreteSubject,"大魔王"));
concreteSubject.attach(new ConcreteObserver(concreteSubject,"小魔王"));
concreteSubject.setStatus("全部毁灭吧");
concreteSubject.notifyAllObservers();
}
}
客户端输出
大魔王状态改变:全部毁灭吧
小魔王状态改变:全部毁灭吧
Process finished with exit code 0
将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象的一致性,我们不希望为了维护一致性而使得各类紧密耦合,使得维护以及拓展变得不方便起来,那么观察者模式的好处就来了,它使得耦合的双方都依赖于抽象,而不是依赖于具体,使得一方的改变不会影响到另一方。
观察者模式主要应用场景有:
1、对一个对象状态的更新需要其他对象同步更新
2、对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节,如消息推送