观察者模式解析
Posted dangolqy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了观察者模式解析相关的知识,希望对你有一定的参考价值。
1.概述
观察者模式(Observer Pattern),是软件设计模式中的一种,又称发布-订阅模式,属于发布-订阅架构的一种应用。
观察者模式定义了对象之间一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。
比如高温预警系统,政府部门和群众需要知道温度情况,就需要关注温度监测系统,当温度过高时系统向政府和群众发出预警。在这个应用之中,政府部门和群众即是观察者,他们关注的对象温度监测系统是被观察者,当温度状态发生变化时,被观察者向观察者发出通知。
2.结构
观察者模式的结构如上图所示。
从图中我们可以看到,观察者模式种包括四个重要角色:
(1)抽象主题角色(即图中的目标,属于被观察者),它提供一个接口,来负责增加和删除观察者对象。
(2)具体主题角色(即图中的具体目标),继承自抽象主题角色,它将有关的状态存入具体观察者对象,在其内部状态发生改变时,给所有注册过的观察者发出通知。
(3)抽象观察者角色:具体观察者的接口。
(4)具体观察者角色:实现接口,接受主题通知的状态以更新自己的状态使之与主题相协调。
3.推数据与拉数据
具体主题在通知观察者更新状态时有两种方式:推数据和拉数据。
推数据:通过参数传递的方式,主题将变化之后的数据全部交给观察者;
拉数据:主题提供获取数据的方法,当观察者需要时自己去拿取。
推数据方式
拉数据方式
4.观察者模式的优缺点
优点:
(1)观察者模式在观察者和被观察者之间建立了一个抽象的耦合。被观察者无需了解任何一个具体观察者,只知道他们之间有一个公共的接口。因此观察者和被观察者可以属于不同的抽象化层次;
(2)观察者模式支持广播通信,被观察者会向所有注册过的观察者发出通知。
缺点:
(1)观察者较多时,通知会花费较长时间;
(2)如果被观察者之间有循环依赖,会触发他们之间的循环调用导致系统崩溃;
(3)没有相应的机制使得观察者知道被观察对象是如何变化的。
5.实例
https://github.com/leotoneo/ObserverDesign/blob/master/ObserverDesign.java
这是一个液位传感器测水位的简单模拟,当水位超过预警线时,传感器通知控制器关闭水阀。
代码较短,也比较明确,是一个推数据方式的例子,其中传感器为被观察者(主题),控制器为观察者(这一点源码注释中写错了)。
(1)主题类(传感器类)
1 class Sensor{ 2 //记录当前水位状态 3 public static int flag = 0; 4 static ArrayList<Controller> arrayList = new ArrayList<Controller>(); 5 //增加被通知的对象 6 public void addLisener(Controller controller){ 7 arrayList.add(controller); 8 } 9 //传感器工作 10 public static void startWrok(){ 11 new Thread(){ 12 13 @Override 14 public void run() { 15 while(true){ 16 Random random = new Random(); 17 flag = random.nextInt(101);//产生0~100的随机数 18 if((flag%2)==0){ 19 System.out.println("警告警告 水位超出警戒线"); 20 }else{ 21 System.out.println("现在一切正常"); 22 } 23 //遍历集合中的每一个控制器,通知他们 24 for(Controller controller: arrayList){ 25 controller.notificationControner(flag); 26 } 27 //休眠1~1.5秒 即1~1.5秒 更新一个状态 28 Random randomTime = new Random(); 29 int time = randomTime.nextInt(501) + 1000; 30 try { 31 Thread.sleep(time); 32 } catch (InterruptedException e) { 33 // TODO Auto-generated catch block 34 e.printStackTrace(); 35 } 36 } 37 } 38 39 }.start(); 40 41 42 } 43 }
(2)抽象观察者(控制器接口)
1 interface Controller { 2 public void notificationControner(int flag); 3 }
(3)具体观察者(两个不同的控制器)
1 //Arm类的控制器(年轻有活力) 2 class Arm implements Controller{ 3 4 @Override 5 public void notificationControner(int flag) { 6 if((flag%2)==0){ 7 System.out.println("Arm ,水位超过警戒线了赶紧关闭水阀吧。。。。"); 8 }else{ 9 System.out.println("Arm,玩会游戏吧现在一切正常"); 10 } 11 12 13 } 14 15 } 16 //AVR类的控制器(岁数大了 ,反应慢了) 17 class AVR implements Controller{ 18 19 @Override 20 public void notificationControner(int flag) { 21 if((flag%2)==0){ 22 System.out.println("AVR,水位过警戒线了,麻烦您老人家给关一下水阀吧!"); 23 }else{ 24 System.out.println("AVR,赶紧歇会吧,现在一切正常"); 25 } 26 27 28 } 29 30 }
参考文章:https://blog.csdn.net/shadow_zed/article/details/75194541
以上是关于观察者模式解析的主要内容,如果未能解决你的问题,请参考以下文章