故事
先来一个与这个模式相似的故事。《无间道》很多人都看多,刘德华是黑社会卧底,梁朝伟是警方卧底,黄秋生是梁朝伟的头头,曾志伟是刘德华的头头。我们这里单单拿黄秋生和曾志伟来说,曾志伟的每一步行动,梁朝伟都会监视,并且向黄秋生报告。这里,梁朝伟就相当于黄秋生的一个具体的眼睛,盯着曾志伟的一举一动,然后黄秋生根据梁朝伟的报告,作出具体反应。同时,我们知道,在黑社会可能不止一个像梁朝伟一样的卧底,所以可能有多个观察者同时观察同一个被观察者。
在现实世界里,需要派出卧底,因为被观察者不会主动报告,但是在代码的里,被观察者却可以主动报告,由此可以省去间谍这一角色,直接由被观察者广播消息,观察者收到消息进行选择性处理。
再具体分析:
曾志伟的所有行为,都可以被观察,但是哪些行为后需要通知观察者,这个在现实世界是被动的东西,在代码里可以化为主动,由具体的被观察者决定此消息是否广播给所有观察者,不同的观察者收到同样的消息,也会进行不同的处理。所以我们需要抽象一下观察者和被观察者
抽象一下:
定义
观察者模式,也叫做发布订阅模式。正式定义为:定义对象间一种一对多的依赖关系,使得每当这个对象的状态改变,所有依赖它的对象都会得到通知并自动更新。
角色
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要开始非法交易了 警局收到消息,开始抓捕
这样,每当被观察者有所举动,且此举动是需要上报的,那么观察者就会收到相应消息,并作出相应的举动
以上就是观察者模式的小结。