文章参考于《设计模式的艺术之道》——刘伟
定义:对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
它的别名有发布-订阅模式、模型-视图模式、源-监听模式,它是一种对象行为型模式。
在观察者模式中有如下角色:
- Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
- ConcreteSubject:具体主题(具体被观察者),包含有经常发生改变的数据,当它状态发生改变时,向其各个观察者发出通知。
- Observer:抽象观察者,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
- ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。它存储了具体观察者的有关状态,它的状态要和具体目标的状态一致。
问题举例:有一个Java知识微信公众号,每当微信公众号的更新的时候就要通知这些订阅的微信用户。将微信公众号当做被观察者,用户当做观察者。好比红绿灯,(被观察者)灯一变,(观察者)车辆就会根据灯的变化而做出反映。具体代码实现:
抽象主题(被观察者)
也就是微信公众号
public interface Subject { //添加订阅者 public void attach(Observer o); //删除订阅者 public void detach(Observer o); //通知订阅者最新消息 public void notifyAllUser(String message); }
具体主题(抽象类的实现)
public class ConcreteSubject implements Subject{ //存储订阅者 private List<Observer> userList = new ArrayList<Observer>(); @Override public void attach(Observer o) { userList.add(o); } @Override public void detach(Observer o) { userList.remove(o); } @Override public void notifyAllUser(String message) { for(Observer ob : userList) { ob.update(message); } } public List<Observer> getUserList() { return userList; } public void setUserList(List<Observer> userList) { this.userList = userList; } }
观察者(抽象类)
订阅公众号的用户
public interface Observer { //更新方法 public void update(String message); }
具体观察者(抽象类的实现)
public class ConcreteObserver implements Observer { private String name; public ConcreteObserver(String name){ this.name = name; } @Override public void update(String message) { System.out.println(name + "同学,公众号更新了" + message); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
客户端调用
public class Client { public static void main(String[] args) { ConcreteSubject subject = new ConcreteSubject(); //创建订阅者 Observer zs = new ConcreteObserver("张三"); Observer ls = new ConcreteObserver("李四"); Observer ww = new ConcreteObserver("王五"); //订阅公众号 subject.attach(zs); subject.attach(ls); subject.attach(ww); //通知消息 subject.notifyAllUser("Java设计模式--观察者模式"); } }
结果:
张三同学,公众号更新了Java设计模式--观察者模式 李四同学,公众号更新了Java设计模式--观察者模式 王五同学,公众号更新了Java设计模式--观察者模式
观察者模式总结
使用场景:
1、主要是用于解决对象之间的行为联动,不过对象的行为不是组合的,是各自独立的。
2、一个对象改变,导致一个或多个对象发生改变,而且不是改变的对象是谁。
3、事件多级触发,构成一种链式触发机制
优点:
1、解除耦合,实现表示层和数据逻辑层的分离;
2、支持广播方式,向所有注册的观察者对象发送通知;
3、观察者与被观察者都依赖与抽象,使得各自变换不会影响另一边。
缺点:
1、如果观察者和被观察者之间存在循环,会进入无线循环转台,导致系统崩溃。
2、观察者模式没有机制让观察者知道,被观察者对象的变化细节,只知道被观察者发生了变化。