观察者模式简介
观察者模式又叫发布订阅(Publish/Subscribe)模式
观察者模式(Observer Pattern)定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
类图:
核心类说明:
Subject: 抽象主题,即为被观察对象,本身维护一个观察者集合。
Observer: 抽象观察者,根据主题状态变化做出相应反应,本身维护一个主题的引用。
使用示例
public interface Subject {
void notify(String msg);
String getState();
String getName();
void addObserver(Observer observer);
void changeState(String state);
}
public class ConcreteSubject implements Subject{
private List<Observer> observers = new ArrayList<>();
private String name;
private String state = "default";
public ConcreteSubject(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public void addObserver(Observer observer){
observers.add(observer);
}
public void changeState(String state){
this.setState(state);
this.notify(state);
}
@Override
public void notify(String msg) {
for(Observer observer : observers){
observer.getMsg(this, name);
}
}
}
public interface Observer {
void getMsg(Subject subject, String msg);
}
public class ConcreteObserver implements Observer {
private String state = "default";
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
@Override
public void getMsg(Subject subject, String msg) {
System.out.println(subject.getName() + " new state: " + subject.getState());
System.out.println(name + " state " + state + " --> " + subject.getState());
this.setState(subject.getState());
}
}
public class Client {
public static void main(String[] args) {
Observer observer1 = new ConcreteObserver("Observer1");
Observer observer2 = new ConcreteObserver("Observer2");
Observer observer3 = new ConcreteObserver("Observer3");
Subject subject1 = new ConcreteSubject("Subject1");
subject1.addObserver(observer1);
subject1.addObserver(observer2);
subject1.addObserver(observer3);
subject1.changeState("State01");
}
}
结果输出:
Subject1 new state: State01
Observer1 state default --> State01
Subject1 new state: State01
Observer2 state default --> State01
Subject1 new state: State01
Observer3 state default --> State01
总结
优缺点
优点: 观察者模式实现了观察者和被观察者的解耦,易于维护、扩展和重用。
缺点:如果存在过多的观察者,运行效率低。效率问题可以考虑使用异步机制解决,但是必须保证异步逻辑自洽。同时还需要注意避免死循环(相互观察)的问题。
使用场景
当一个对象的改变需要同时改变其他对象的时候,可以考虑使用观察者模式。