分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net
观察者模式对于我们来说,真是再简单不过了。无外乎两个操作,观察者订阅自己关心的主题和主题有数据变化后通知观察者们。
首先,需要定义主题,每个主题需要持有观察者列表的引用,用于在数据变更的时候通知各个观察者:
public class Subject { private List
observers = new ArrayList
(); private int state; public int getState() { return state; } public void setState(int state) { this.state = state; // 数据已变更,通知观察者们 notifyAllObservers(); } // 注册观察者 public void attach(Observer observer) { observers.add(observer); } // 通知观察者们 public void notifyAllObservers() { for (Observer observer : observers) { observer.update(); } } }
定义观察者接口:
public abstract class Observer { protected Subject subject; public abstract void update(); }
其实如果只有一个观察者类的话,接口都不用定义了,不过,通常场景下,既然用到了观察者模式,我们就是希望一个事件出来了,会有多个不同的类需要处理相应的信息。比如,订单修改成功事件,我们希望发短信的类得到通知、发邮件的类得到通知、处理物流信息的类得到通知等。
我们来定义具体的几个观察者类:
public class BinaryObserver extends Observer { // 在构造方法中进行订阅主题 public BinaryObserver(Subject subject) { this.subject = subject; // 通常在构造方法中将 this 发布出去的操作一定要小心 this.subject.attach(this); } // 该方法由主题类在数据变更的时候进行调用 @Override public void update() { String result = Integer.toBinaryString(subject.getState()); System.out.println("订阅的数据发生变化,新的数据处理为二进制值为:" + result); } } public class HexaObserver extends Observer { public HexaObserver(Subject subject) { this.subject = subject; this.subject.attach(this); } @Override public void update() { String result = Integer.toHexString(subject.getState()).toUpperCase(); System.out.println("订阅的数据发生变化,新的数据处理为十六进制值为:" + result); } }
客户端使用也非常简单:
public static void main(String[] args) { // 先定义一个主题 Subject subject1 = new Subject(); // 定义观察者 new BinaryObserver(subject1); new HexaObserver(subject1); // 模拟数据变更,这个时候,观察者们的 update 方法将会被调用 subject.setState(11); } // Output: /* 订阅的数据发生变化,新的数据处理为二进制值为:1011 订阅的数据发生变化,新的数据处理为十六进制值为:B */
当然,JDK 也提供了相似的支持,具体的可以参考 java.util.Observable 和 java.util.Observer 这两个类。
实际生产过程中,观察者模式往往用消息中间件来实现,如果要实现单机观察者模式,笔者建议读者使用 Guava 中的 EventBus,它有同步实现也有异步实现。
还有,即使是上面的这个代码,也会有很多变种,大家只要记住核心的部分,那就是一定有一个地方存放了所有的观察者,然后在事件发生的时候,遍历观察者,调用它们的回调函数。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216349.html原文链接:https://javaforall.net
