观察者模式.

阅读目录 一、概念 二、Demo实现 三、总结 回到顶部 一、概念 观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。 观察者模式四个角色:  1、抽象主题:定义对观察者管理的接口,包括 订阅、取消订阅、通知接口。  2、具体主题:把所有观察者对象的引用保存在一个聚集(比如ArrayList对象)里,实现抽象主题的接口,并在更新时通知观察者。  3、抽象观察者:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。  4、具体观察者:实现抽象观察者定义的接口,得到主题通知的数据(pull or push),并实现自己的逻辑。 主题 + 观察者 = 观察者模式,可以用报纸订阅服务来模拟这个模式 —— 报纸是主题,订阅报纸的人是观察者。观察者可以选择是否订阅或者退订主题。 回到顶部 二、Demo实现 1、主题 java.util 包中内置了一个抽象主题 Observable 类(有弊端,下文会提到),可以选择继承 Observable 类作为具体主题角色。 @AllArgsConstructor @Getter public class WeatherData extends Observable { /** * 温度 */ private Float temperature; /** * 湿度 */ private Float humidity; /** * 压力 */ private Float pressure; /** * 假设改变的时候这个方法会被调用 */ public void measurementsChanged() { setChanged(); notifyObservers(); // 这种不带参数的方式,由观察者 pull 自己想要的数据。要什么数据由观察者自己决定。 //notifyObservers(Object arg) // 这种带参数的方式,由主题 push 数据。传什么数据由主题决定。(推荐) } } 2、观测者 java.util 包中内置了一个抽象观察者 Observer 接口,可以选择实现 Observer 接口的 update 方法作为具体观察者角色,做更新的操作。 湿度观察者: public class HumidityObserver implements Observer { public HumidityObserver(Observable observable) { // 订阅主题 observable.addObserver(this); } @Override public void update(Observable o, Object arg) { if (o instanceof WeatherData) { WeatherData weatherData = (WeatherData) o; Float humidity = weatherData.getHumidity(); System.out.println("我是一个湿度观察者,我现在的湿度是:" + humidity); } } } 压力观察者: public class PressureObserver implements Observer { public PressureObserver(Observable observable) { // 订阅主题 observable.addObserver(this); } @Override public void update(Observable o, Object arg) { if (o instanceof WeatherData) { WeatherData weatherData = (WeatherData) o; Float pressure = weatherData.getPressure(); System.out.println("我是一个压力观察者,我现在的压力是:" + pressure); } } } 温度观察者: public class TemperatureObserver implements Observer { public TemperatureObserver(Observable observable) { // 订阅主题 observable.addObserver(this); } @Override public void update(Observable o, Object arg) { if (o instanceof WeatherData) { WeatherData weatherData = (WeatherData) o; Float temperature = weatherData.getTemperature(); System.out.println("我是一个温度观察者,我现在的温度是:" + temperature); } } } 3、测试 public static void main(String[] args) { // 具体主题实现 WeatherData weatherData = new WeatherData(24.0F,152F,100F); // 观察者订阅 new HumidityObserver(weatherData); new PressureObserver(weatherData); new TemperatureObserver(weatherData); // 事件发生 weatherData.measurementsChanged(); } 4、Observable 的弊端 Observable 是一个“类”,而不是一个接口。所以你只能选择继承它,实现自己的具体主题,这大大限制了 Observable 的复用潜力,毕竟 Java 不支持多重继承。 Observable 的 setChanged 方法是 protected 属性的,因此你除了选择继承 Observable 类,甚至无法使用组合来使用它。 如果有必要的话可以实现自己的 Observable 接口,不要害怕,这并不难。(链接代码中有示例) avatar tips:"抽象"主题 和 具体主题标反了。汗~ 演示源代码:https://github.com/JMCuixy/design-patterns 回到顶部 三、总结 设计原则:观察者模式是为了交互对象之间的松耦合设计而努力。 应用场景:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。 优点:主题是真正拥有数据的人,观察者是主题的依赖者,在数据变化时更新,这样比起让许多对象控制通一份数据类,可以得到更加干净的OO设计。 缺点:在应用观察者模式时需要考虑一下开发效率和运行效率的问题,因为在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,我们一般会采用异步实现。而且必须保证投递是以自恰的方式进行的。https://www.cnblogs.com/jmcui/p/9940363.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信