观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。
比如,许多人关注了一个微博大牛,当他更新了微博时,关注他的人都会收到通知。
就是当一个对象被修改时,会通知它的依赖对象。
观察者模式属于行为型模式。
观察者模式的别名包括:
发布-订阅(Publish/Subscribe)模式、
模型-视图(Model/View)模式、
源-监听器(Source/Listener)模式
或从属者(Dependents)模式。
观察者的结构:
有如下角色:
- Subject: 目标/被观察者
- ConcreteSubject:具体目标
- Observer: 观察者
- ConcreteObserver:具体观察者
怎么做
首先是主题Subject类的实现,它使用集合持有订阅者,订阅者通过attach
方法订阅主题,detach
方法取消订阅,当主题的state发生变化时,通过notifyObservers
通知订阅者,主题状态有更新:
/**
* 主题,被观察对象
*/
public class Subject {
private List<Observer> observers = new ArrayList<>();//订阅者链表
private int state;//主题状态
public void attach(Observer observer){
observers.add(observer);
}
public void detach(Observer observer){
if(observer!=null){
observers.remove(observer);
}
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
notifyObservers();
}
public void notifyObservers(){
for(Observer observer:observers){
observer.update(this);
}
}
}
然后时订阅者类的实现,一般是一个抽象类或者接口:
/**
* 观察者
*/
public interface Observer {
void update(Subject subject);
}
接着时具体观察者类的实现,在update
方法中对主题状态改变进行具体操作:
public class BinaryObserver implements Observer {
@Override
public void update(Subject subject) {
System.out.println("Binary String:"+Integer.toBinaryString(subject.getState()));
}
}
public class HexObserver implements Observer {
@Override
public void update(Subject subject) {
System.out.println("Hex String:"+Integer.toHexString(subject.getState()));
}
}
public class OctalObserver implements Observer {
@Override
public void update(Subject subject) {
System.out.println("Octal String:"+Integer.toOctalString(subject.getState()));
}
}
最后,我们写个Client
类看看具体应用:
public class Client {
public static void main(String[] args) {
Subject subject = new Subject();
HexObserver hexObserver = new HexObserver();
OctalObserver octalObserver = new OctalObserver();
BinaryObserver binaryObserver = new BinaryObserver();
//观察者订阅主题
subject.attach(hexObserver);
subject.attach(octalObserver);
subject.attach(binaryObserver);
System.out.println("Set state:15");
subject.setState(15);//设置状态
System.out.println("-----------------");
//取消订阅主题
subject.detach(octalObserver);
System.out.println("Set state:24");
subject.setState(24);//改变状态
}
}
运行结果: