目的:

Observer模式的宗旨是在多个对象之间定义一对多的关系,以便当一个对象状态改变时,其他所有依赖于这个对象的对象都能得到通知,并被自动更新。常用于业务逻辑层与表现层的分离

需求:由GUI引起的

图一

实现图一所示的图形界面。当滑动Slider时,界面中的两个曲线图像需要改变,底部的tPeak显示也需要改变。两个曲线由以下两个公式确定:

最初的模型:

借助于Observer模式,当某个对象发生变化时,关注该对象的其他对象可以被通知。最初的类层次结构如图二。

图二

上图中,ShowBallistics作为表现层元素,包含了burnPanel和thrustPanel这两个BallisticsPanel组件和一个slider滑动条组件,同时由于slider控制前台的显示,ShowBallistics实现了ChangeListener接口并在JSlider组件中注册,当JSlider发生变化时,JSlider依赖注册的ShowBallistics对象调用stateChanged(ChangeEvent e)方法,在该方法中,通过调用burnPanel和thrustPanel对象的setTPeak()方法重画曲线,调用valueLabel (JLabel)的setText()方法刷新显示。

分析这个应用, JSlider改变引起burnPanel、thrustPanel和valueLabel这三个组件的重刷。根据上面的实现,表现层业务的重刷与业务逻辑层值的改变纠集在一个类当中。这显然是不合适的,简单的,当表现层的需求改变,如不再是画曲线而是画动画,就必须将BallisticsPanel组件改变为其他的显示组件,势必要对ShowBallistics类做出改变。因此我们引入基于Observer的MVC框架实现业务层与表现层的分离,使得两者能够独立变化,也能引起事件的响应。

与Bridge模式类比,以设备驱动为例,Bridge模式将具有一组类似接口的类提升出面向外部应用层调用的接口,实现了驱动具体实现与外部抽象逻辑(怎么用)的分离,方便驱动类的扩展,方便外部逻辑类的自由扩展。所以Bridge模式的关键在扩展,Observer模式的关键在通知

MVC架构:

综述的,随着应用程序和系统规模的膨胀,必须对责任进行分解和重分解,使每个类保持较小的规模,以便系统维护。

Model/View/Control是将对象与显示它的GUI(View/Control)分离。Java中,基于Observer(观察者)和Observable(被观察者)支持了Observer模式的标准实现。

分析本应用,实际上就是如何得到tPeak并以某几种方式显示tPeak的问题。因此在重构中,首先抽象出模型tPeak,如图三

图三

其中,depend on 关系表示在构造对象是需要传入Tpeak对象。Is Associated with关系表示是成员对象。在模型Tpeak中,当JSlider发生改变时,在stateChange方法中调用Tpeak的setValue方法,实现如下:

  1. public void setValue(double value) {
  2.     this.value = value;
  3.     setChanged();
  4.     notifyObservers();
  5. }

可以看到,Tpeak作为Observable,是Observer刷新操作的调用者,作为model,又是前台(JSlider)响应的接收者,可以视为完成了一次从前台到后台再到前台的过程。

对于Observable的底层实现,保持一个Observer的组合,实现一对多的依赖。涉及的操作,无非是增删改查以及触发事件的响应。

  1. public class Observable {
  2.     private boolean changed = false;
  3.     private Vector obs;
  4.     public Observable() {
  5.    obs = new Vector();
  6.     }
  7.     public synchronized void addObserver(Observer o) {
  8.         if (o == null)
  9.             throw new NullPointerException();
  10.    if (!obs.contains(o)) {
  11.        obs.addElement(o);
  12.    }
  13.     }
  14.     public synchronized void deleteObserver(Observer o) {
  15.         obs.removeElement(o);
  16.     }
  17.  
  18.     public void notifyObservers() {
  19.    notifyObservers(null);
  20.     }
  21.     public void notifyObservers(Object arg) {
  22.         Object[] arrLocal;
  23.  
  24.    synchronized (this) {
  25.        if (!changed)
  26.                 return;
  27.             arrLocal = obs.toArray();
  28.             clearChanged();
  29.         }
  30.  
  31.         for (int i = arrLocal.length-1; i>=0; i--)
  32.             ((Observer)arrLocal[i]).update(this, arg);
  33.     }
  34.     public synchronized void deleteObservers() {
  35.    obs.removeAllElements();
  36.     }
  37.     protected synchronized void setChanged() {
  38.    changed = true;
  39.     }
  40.     protected synchronized void clearChanged() {
  41.    changed = false;
  42.     }
  43.     public synchronized boolean hasChanged() {
  44.    return changed;
  45.     }
  46.     public synchronized int countObservers() {
  47.    return obs.size();
  48.     }
  49. }

对于前台的Observer,在构造函数中向对应的Observable进行注册,发生响应时调用update()方法。

  1. public class BallisticsLabel extends JLabel implements Observer {
  2.     public BallisticsLabel(Tpeak tPeak) {
  3.         tPeak.addObserver(this);
  4.     }
  5.     public void update(Observable obj, Object arg) {
  6.         setText(Format.formatToNPlaces(((Tpeak) obj).getValue(), 2));
  7.         repaint();
  8.     }
  9. }

责任型模式一:Observer(观察者)模式的更多相关文章

  1. Java设计模式——Observer(观察者)模式

    在多个对象之间建立一对多的关系,以便当一个对象状态改变的时候.其它全部依赖于这个对象的对象都能得到通知,并被自己主动更新. 适用情况: 当一个抽象模型有两个方面,当中一个方面依赖于还有一方面. 将这二 ...

  2. 设计模式 之 观察者(Observer)模式

    观察者(observer)模式定义了一对多的依赖关系,让多个观察者对象能够同时监听某一主题对象.这个主题对象中的状态发生改变时,就会通知所有的观察者对象. 观察者模式的结构图: 结构中各个部分的含义: ...

  3. 观察者(Observer)模式

    http://www.cnblogs.com/zhenyulu/articles/73723.html 一. 观察者(Observer)模式 观察者模式又叫做发布-订阅(Publish/Subscri ...

  4. 设计模式的征途—15.观察者(Observer)模式

    在日常生活中,交通信号灯指挥者日益拥挤的城市交通.红灯亮,汽车停止:绿灯亮,汽车继续前行:在这个过程中,交通信号灯是汽车的观察目标,而汽车则是观察者.随着交通信号灯的变化,汽车的行为也会随之变化,一盏 ...

  5. 设计模式:观察者(Observer)模式

    设计模式:观察者(Observer)模式 一.前言   观察者模式其实最好的名称应该是“发布订阅”模式,和我们现在大数据之中的发布订阅方式比较类似,但是也有区别的地方,在上一个设计模式,我们学习的是仲 ...

  6. 观察者(Observer)模式 * 委托事件

    观察者(Observer)模式:定义了一种一对多的依赖关系.让多个观察者对象同时监听某一个主题对象.   这个主题对象发生变化时会通知所有观察者对象,使他们字段更新自己 /* * 抽象主题(Subje ...

  7. 行为型模式之Observer模式

    观察者模式(又被称为发布-订阅模式.模型-视图模式.源-收听者模式或从属者模式) 观察者模式中,一个目标对象管理所有依赖于它的观察者对象,并且在它本身的状态改变时主动发出通知. 应用场景 拍卖会可以认 ...

  8. ZooKeeper增加Observer部署模式提高性能(转)

    除了Leader和Follow模式之外,还有第三种模式:Observer模式. Observer:在不伤害写性能的情况下扩展ZooKeeper. 虽然通过Client直接连接到ZooKeeper集群的 ...

  9. 设计模式15---观察者模式(Observer Pattern)

    一.观察者模式定义 观察者模式定义: Define a one-to-many dependency between objects so that when one object changes s ...

  10. 学习javascript设计模式之发布-订阅(观察者)模式

    1.发布-订阅模式又叫观察者模式,它定义对象之间一种一对多的依赖关系. 2.如何实现发布-订阅模式 2-1.首先指定好发布者 2-2.给发布者添加一个缓冲列表,用户存放回调函数以便通知订阅者 2-3. ...

随机推荐

  1. bzoj 3709: [PA2014]Bohater 贪心

    题目: 在一款电脑游戏中,你需要打败\(n\)只怪物(从\(1\)到\(n\)编号).为了打败第\(i\)只怪物,你需要消耗\(d_i\)点生命值,但怪物死后会掉落血药,使你恢复\(a_i\)点生命值 ...

  2. 51nod 1685 第K大区间2

    定义一个长度为奇数的区间的值为其所包含的的元素的中位数.中位数_百度百科 现给出n个数,求将所有长度为奇数的区间的值排序后,第K大的值为多少. 样例解释: [l,r]表示区间的值[1]:3[2]:1[ ...

  3. YII1.1分页

    一.控制器 $criteria = new CDbCriteria(); //这里可以加一些条件 $criteria->addCondition('parent_id='.$this->c ...

  4. 自编jQuery插件实现模拟alert和confirm

    现在绝大多数网站都不用自带的alert和confirm了,因为界面太生硬了.因此这个插件就这样产生了自己定制一个的想法...... 啥也不说,先上图,有图有真相 :) 现在绝大多数网站都不用自带的al ...

  5. zabbix上的宏(macro)介绍

    宏:macro,预设的文本替换模式: 宏是一种抽象概念(Abstraction),它根据一些列预定义的规则替换一定的文本模式,而解释或编译器在遇到宏时会自动进行这一模式替换.类似地,zabbix基于宏 ...

  6. PHP7卓越性能背后的原理有哪些?

    作者:韩天峰链接:http://www.zhihu.com/question/38148900/answer/75115687来源:知乎 PHP7在运行原理上与PHP5相比并没有变化,这与hhvm不同 ...

  7. GWT中自定义你的"cell"

    GWT内部提供了CellTable组件,它允许自由增加column以及cell,在设定column之后就是在其中填充cell了.但GWT所提供的CellTable样式确实不敢恭维,为了解决这一问题,在 ...

  8. (转)配置ORACLE 11g绿色版客户端和PLSQL环境

    本文转载自:http://my.oschina.net/jang/blog/83009 本方法是通过使用ORACLE官方提供的精简版客户端,即绿色免安装的客户端. 下载地址(此处提供的是官方各版本下载 ...

  9. SQL基础(1)

    1.SQL简介 (1)什么是SQL? SQL指结构化查询语言 SQL使我们有能力访问数据库 SQL是一种 ANSI 的标准计算机语言 (2)SQL 能做什么? SQL面向数据库执行查询 SQL可从数据 ...

  10. HDLM命令dlnkmgr详解之四_monitor/offline/online

    1. monitor 以一定的时间间隔监控hba或cha口的IO信息. 命令格式 监控hba口的IO信息: dlnkmgr monitor -hbaid HBA_ID [-intvl Interval ...