故事
先来一个与这个模式相似的故事。《无间道》很多人都看多,刘德华是黑社会卧底,梁朝伟是警方卧底,黄秋生是梁朝伟的头头,曾志伟是刘德华的头头。我们这里单单拿黄秋生和曾志伟来说,曾志伟的每一步行动,梁朝伟都会监视,并且向黄秋生报告。这里,梁朝伟就相当于黄秋生的一个具体的眼睛,盯着曾志伟的一举一动,然后黄秋生根据梁朝伟的报告,作出具体反应。同时,我们知道,在黑社会可能不止一个像梁朝伟一样的卧底,所以可能有多个观察者同时观察同一个被观察者。
在现实世界里,需要派出卧底,因为被观察者不会主动报告,但是在代码的里,被观察者却可以主动报告,由此可以省去间谍这一角色,直接由被观察者广播消息,观察者收到消息进行选择性处理。
再具体分析:
曾志伟的所有行为,都可以被观察,但是哪些行为后需要通知观察者,这个在现实世界是被动的东西,在代码里可以化为主动,由具体的被观察者决定此消息是否广播给所有观察者,不同的观察者收到同样的消息,也会进行不同的处理。所以我们需要抽象一下观察者和被观察者
抽象一下:
定义
观察者模式,也叫做发布订阅模式。正式定义为:定义对象间一种一对多的依赖关系,使得每当这个对象的状态改变,所有依赖它的对象都会得到通知并自动更新。
角色
Subject被观察者
定义被观察者必须实现的职责,必须能动态的增加、取消观察者。一般为抽象类或接口,仅仅完成被观察者必须实现的职责:管理观察者并通知观察者。
Observer观察者
观察者接收到消息后,对信息进行处理
ConcreteSubject具体的被观察者
定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知
ConCreteObserver
每个观察者在接收到消息后的处理逻辑反应不同,各个观察者有自己的处理逻辑。
代码模版
被观察者
public abstract class Subject {
//观察者数组
private ArrayList<Observer> observerArrayList = new ArrayList<>();
//增加一个观察者
public void addObserver(Observer o) {
this.observerArrayList.add(o);
}
//删除一个观察者
public void deleteObserver(Observer o) {
this.observerArrayList.remove(o);
}
//通知所有观察者
public void notifyObservers() {
for (Observer o : this.observerArrayList) {
o.update();
}
}
}
具体的被观察者
public class ConcreteSubject extends Subject {
//具体的业务
public void doSomething() {
/*
业务逻辑
*/
super.notifyObservers();
}
}
观察者
public interface Observer {
//更新方法
public void update();
}
具体的观察者
public class ConCreteObserver implements Observer {
//实现更新方法
@Override
public void update() {
System.out.println("收到信息,进行处理");
}
}
场景
public class Client {
public static void main(String[] args) {
//创建一个被观察者
ConcreteSubject subject = new ConcreteSubject();
//创建观察者
Observer observer = new ConCreteObserver();
//添加观察者
subject.addObserver(observer);
//被观察者开始活动
subject.doSomething();
}
}
简单实例
以上面的故事为例,我们创建下面的类
public class ZengZW extends Subject {
public void illegalTrade() {
System.out.println("我ZZW要开始非法交易了");
super.notifyObservers();
}
}
public class HuangQS implements Observer{
@Override
public void update() {
System.out.println("警局收到消息,开始抓捕");
}
}
public class Client {
public static void main(String[] args) {
//创建一个被观察者
ZengZW zengZW = new ZengZW();
//创建观察者
HuangQS huangQS = new HuangQS();
//添加观察者
zengZW.addObserver(huangQS);
//被观察者开始活动
zengZW.illegalTrade();
}
}
输出结果
我ZZW要开始非法交易了
警局收到消息,开始抓捕
这样,每当被观察者有所举动,且此举动是需要上报的,那么观察者就会收到相应消息,并作出相应的举动