文章参考于《设计模式的艺术之道》——刘伟
定义:对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
它的别名有发布-订阅模式、模型-视图模式、源-监听模式,它是一种对象行为型模式。
在观察者模式中有如下角色:
- 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、观察者模式没有机制让观察者知道,被观察者对象的变化细节,只知道被观察者发生了变化。