定义:
观察者模式又叫发布订阅模式,定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
角色分类:
- Subject被观察者:定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。
- Observer观察者:观察者接收到消息后,即进行update(更新方法)操作,对接收到的信息进行处理。
- ConcreteSubject具体的被观察者:定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
- ConcreteObserver具体的观察者:每个观察在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑。
代码实现:
package com.observer;
import java.util.ArrayList;
import java.util.List;
/**
* 观察者模式
* 被观察者抽象类
*/
public abstract class Subject {
//观察者名单
private List<Observer> observerList = new ArrayList<>();
//添加一个观察者
public void addObserver(Observer obs){
this.observerList.add(obs);
}
//删除一个观察者
public void deleteObserver(Observer obs){
this.observerList.remove(obs);
}
//通知所有观察者
public void notifyObserver(){
for (Observer obs:this.observerList) {
obs.update();
}
}
}
package com.observer;
/**
* 观察者模式
* 具体的被观察者
*/
public class ConcreteSubject extends Subject {
private String name;
public ConcreteSubject(String name){
this.name = name;
}
//具体被观察者的业务
public void push(){
System.out.println(name+"发了条短信");
super.notifyObserver();//通知所有观察者
}
}
package com.observer;
/**
* 观察者模式
* 观察者抽象类
*/
public abstract class Observer {
public void update(){
}
}
package com.observer;
/**
* 观察者模式
* 具体的观察者
* 观察被观察者的动作
*/
public class ConcreteObserver extends Observer{
private String observerName;
public ConcreteObserver(String observerName){
this.observerName = observerName;
}
public void update() {
System.out.println(observerName+"得知了短信内容");
}
}
public class Client {
public static void main(String[] args) {
//被观察者张三
ConcreteSubject zhangsan = new ConcreteSubject("张三");
//观察者李四
ConcreteObserver lisi = new ConcreteObserver("李四");
zhangsan.addObserver(lisi);
zhangsan.push();
}
}
//执行结果
张三发了条短信
李四得知了短信内容
代码中完成了被观察者张三发了条短信,观察者李四得到了短信内容。张三允许李四得到自己发的短信内容,而观察者改成任何人,只要继承了观察者类Observer。
总结:
观察者模式中观察者和被观察者是抽象耦合,提供了可扩展性,无论是扩展观察者还是被观察者。观察中模式完成的是单一触发机制,就是一种情况造成多种情况的扩散,使其形成一个触发链。不过随着触发链的延深,也会造成开发调试困难的情况,这也是观察者模式的弊端之一,同时被被观察者管理者观察者。
观察者模式不仅通过抽象类,也可以通过接口的形式来时松耦合。观察者被观察者是通过接口关联,并不需要具体的实现类。任何一方的具体业务的修改,不会影响对方,这也符合开闭原则。
参考《设计模式之禅》秦小波著