观察者模式(Observer Pattern)也叫作发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式。这个模式的一个最重要的做用就是解耦。也就是将被观察者和观察者进行解耦,使得他们之间的依赖性更小,甚至作到毫无依赖。java
观察者模式的定义:该模式定义了对象之间的一对多依赖关系,Subject 对象是一,Observer 对象是多。当 Subject 对象的状态发生改变时,全部依赖于该 Subject 对象的 Observer 对象都会获得通知,而且自动更新。多线程
仔细分析定义,要精确理解观察者模式主要注意三点:ide
定义了对象间的一对多依赖关系。this
当 Subject 对象的状态发生改变时,全部依赖于该 Subject 对象的 Observer 对象都会获得通知。线程
Observer 对象获得通知后,会自动更新,而不是被动。code
通过上面的分析,下面我用代码简单实现上述逻辑。server
1.首先须要定义一个观察者对象,内部含有data数据(getter、setter、构造方法、toString)。对象
public class Observer { private String data; public Observer(String data) { this.data = data; } public String getData() { return data; } public void setData(String data) { this.data = data; } @Override public String toString() { return "Observer{" + "data='" + data + '\'' + '}'; } }
2.其次定义主题对象,主题对象内部提供观察者绑定(register)的接口,而且能够更新(update)所绑定的观察者对象。继承
public class Subject { private List<Observer> list = new ArrayList<>(); public void register(Observer observer){ list.add(observer); } public void update(){ list.forEach(observer -> { observer.setData("new"); System.out.println(observer.toString()); }); } }
3.最后就是main方法。接口
public static void main(String[] args) { Subject subject = new Subject(); for (int i = 0; i < 3; i++) { Observer observer = new Observer("old"); subject.register(observer); System.out.println(observer.toString()); } System.out.println("update..."); subject.update(); }
控制台打印
Observer{data='old'} Observer{data='old'} Observer{data='old'} update... Observer{data='new'} Observer{data='new'} Observer{data='new'}
看到这里你也许会问:这就是观察者模式?这么简单?你莫不是在逗我?
是的,这就是观察者模式。咱们从观察者模式的定义出发,抽取出关键的3点核心思想,对比代码和三点思想,是否是完美一致?百度一下"观察者模式",实现逻辑大都是复杂高深,其实就核心的思想来讲,上面的示例足够了,其它扩展要以具体的业务需求来决定。好比:
Subject 角色是应该定义成类?好比 内置的 java.util.Observable;仍是应该定义成接口,以规避Java不支持多重继承的问题?
应该在何时订阅主题(或者说注册观察者)?是实例化观察者对象的同时?仍是由客户自主决定?
是否应该实现取消订阅功能(或者说取消注册)?
主题对象通知观察者时,是否携带消息?换句话说,是“推”消息?仍是“拉”消息?
是否支持多线程?