文档章节

观察者模式

noob_fly
 noob_fly
发布于 09/26 20:59
字数 760
阅读 3
收藏 0

意图:

在对象的内部状态发生变化时,自动通知外部对象进行响应。

构成

 被观察者:内部状态有可能被改变,而且又需要通知外部的对象。
 观察者:需要对内部状态的改变做出响应的对象。

Java实现

 Java的API中提供了Observer模式的实现。具体由java.util.Observable类和java.util.Observer接口完成。

Observable 

public class Observable {
    private boolean changed = false;
    private Vector obs;


    public Observable() {
        obs = new Vector();
    }

   
    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

...


 setChanged():设置内部状态为已改变。

notifyObservers(Object obj):通知观察者所发生的改变,参数obj是一些改变的信息

 protected synchronized void setChanged() {
        changed = true;
  }
 
 public void notifyObservers(Object arg) {
       
        Object[] arrLocal;

        synchronized (this) {
          
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

Observer   

 update(Object obj):响应被观察者的改变,其中obj就是被观察者传递过来的信息,该方法会在notifyObservers被调用时自动调用。

public interface Observer {

    void update(Observable o, Object arg);
}

使用

  1. 创建一个被观察者,继承java.util.Observable
  2. 创建一个观察者,实现java.util.Observer接口
  3. 注册观察者,调用addObserver(Observer observer)
  4. 在被观察者改变对象内部状态的地方,调用setChanged()方法,然后调用notifyObservers(Object)方法,通知被观察者
  5. 在观察者的update(Object)方法中,对改变做出响应。

好处

  • 被观察者只需要知道谁在观察它,无需知道具体的观察细节;
  • 被观察者一旦发生变化,只需要通过广播的方式告知观察者,至于消息如何到达则不需知道。这样的话无疑消除了被观察者和观察者之间通信的硬编码
  • 当一个被观察者同时被多个观察着观察时,观察者可以只选择自己感兴趣的事件,而忽略其它的事件
  • 多个观察者组合起来可以形成一个观察链,如果一旦需要回滚多个操作,此时观察链可以发挥作用
  • 观察者可以实时对被观察对象的变化做出响应,例如自动告警、中断运行等

场景

屏蔽线程间的通信机制:eg. 两个线程之间,主线程可以作为观察者,执行线程是被观察者,彼此之间只知道对方存在,但不知道通信的细节;
消除硬编码:如果没有Observer模式,则只能采用回调的方式,或者在代码中显示地调用观察者;
优化异常机制:特别适合在异常发生时向顶层监控,减少try-catch代码量;
 

© 著作权归作者所有

共有 人打赏支持
下一篇: 工厂模式
noob_fly
粉丝 4
博文 76
码字总数 79656
作品 0
广州
程序员
私信 提问
【设计模式笔记】(十六)- 代理模式

一、简述 代理模式(Proxy Pattern),为其他对象提供一个代理,并由代理对象控制原有对象的引用;也称为委托模式。 其实代理模式无论是在日常开发还是设计模式中,基本随处可见,中介者模式中...

MrTrying
06/24
0
0
设计模式已经陨落了?

你现在是坐在一个程序员旁边吗?如果是的话,那么在你读下面的段落之前,有一个简单的实验。让他们到一边去,问问他们两个问题并记录下答案。首先问他们“什么是设计模式?”然后再问“说出你...

oschina
2014/03/11
9.1K
69
《PHP设计模式大全》系列分享专栏

《PHP设计模式大全》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页...

kaixin_code
11/06
0
0
设计模式梳理(一)

设计模式梳理(一) 总体来说设计模式分为三大类: @案例源码地址:https://gitlab.com/lxqxsyu/DisgnPattern 创建型模式 简单工厂模式 工厂类是整个模式的关键。它包含必要的判断逻辑,能够...

lxq_xsyu
2017/11/02
0
0
Ubuntu中vi卸载与安装/使用模式

Ubuntu中安装的vi是vim-common版本,与centos系统中vi使用方式不同,编辑使用不惯, 遂卸载重装,卸载命令:sudo apt-get remove vim-common 卸载完毕后重新安装;输入命令:sudo apt-get in...

唐十三郎
11/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Android :报错Your project path contains non-ASCII characters.

报错内容如下 Your project path contains non-ASCII characters. This will most likely cause the build to fail on Windows. Please move your project to a different directory. See ht......

lanyu96
10分钟前
0
0
[LintCode] Number of Islands(岛屿个数)

描述 给一个01矩阵,求不同的岛屿的个数。 0代表海,1代表岛,如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。 样例 在矩阵: [ [1, 1, 0, 0, 0], [0, 1, 0, 0, ...

honeymose
11分钟前
0
0
Nginx平滑添加模块

Nginx已经编译安装并运行了一段时间, 然后某一天, 发现需要用到某个模块但当初没有编译, 这个时候怎么办呢? 卸载重新安装肯定可以的, 如果Nginx版本没有变更的话, 则有一个相对平滑的方法来添...

老菜鸟0217
15分钟前
1
0
spark安装测试

spark安装测试 由于本地已经安装好hadoop相关组件,所以本文是在yarn的基础上对spark进行安装及测试 确保hdfs及yarn成功启动,hadoop版本为2.7.3 安装scala,由于本人安装的spark是2.4.0,对应...

-九天-
29分钟前
3
0
周末看完了《电能计量自动化技术》

整体质量还行,下面分别将心得记录如下: 第一章:发展历程可以看看,现在算是智能电网阶段 2:讲主站系统。以文件进行各模块的交互很值得思考,尤其是批量数据,多团队合作的情况下。另外线...

max佩恩
49分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部