观察者模式
观察者模式主要解决事件监听器和发布订阅模式问题
类图:
如果一个主题只有一个观察者,观察者模式就是事件监听器
如果一个主题只有多个观察者,观察者模式就是发布订阅
观察者:
public interface Observer {
public void update();
public void subscribeTo(Subject subject);
}
public class ConcretorObserver1 implements Observer {
@Override
public void update() {
System.out.println(this.getClass().getName() + "update");
}
@Override
public void subscribeTo(Subject subject) {
subject.attach(this);
}
}
public class ConcretorObserver2 implements Observer {
@Override
public void update() {
System.out.println(this.getClass().getName() + "update");
}
@Override
public void subscribeTo(Subject subject) {
subject.attach(this);
}
}
主题:
public interface Subject {
public void attach(Observer o);
public void detach(Observer o);
public void notifyObservers();
}
public class ConcretorSubject implements Subject {
private List<Observer> observers;
public ConcretorSubject() {
super();
observers = new ArrayList<Observer>();
}
@Override
public void attach(Observer o) {
observers.add(o);
}
@Override
public void detach(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
客户端:
其实我们可能更习惯订阅某一主题(方法一),但也有一些场景可能用到需要主题加入观察者,多见于主题需要挑选观察者的情况(比如保密会议)
public static void main(String[] args) {
Subject subject = new ConcretorSubject();
Observer o1 = new ConcretorObserver1();
Observer o2 = new ConcretorObserver2();
// 方式一:以观察者订阅主题
o1.subscribeTo(subject);
o2.subscribeTo(subject);
//方式二:以主题加入观察者
// subject.attach(o1);
// subject.attach(o2);
subject.notifyObservers();
}
输出:
方式一和方式二的输出一样
ConcretorObserver1update
ConcretorObserver2update