设计模式<三>观察者模式

观察者模式

需求分析

  1. 需求1,一个小孩哭了,爸爸喂,妈妈抱,狗叫…(一个对象有一定的反应,另外的几个不同的对象做出连锁反应)
  2. 需求2,可以根据小孩是哭还是笑还是…做出不同的反应。(能够根据不同的事件做出不同的反应)
  3. 需求3,爸爸可以把小孩的状态由哭变成笑。(能够调整事件源对象的状态) ----
  4. 需求4:小孩可以根据自己的不同状态,来决定自己是让爸爸处理还是妈妈处理。 — 结合命令模式

上面把观察者模式结合命令模式进行扩展。通知观察者,使用命令模式,使得观察者和被观察者解耦。

再加上责任链模式,可以动态的增加和减少功能

JDK的观察者模式

  1. 更清晰的语义,状态改变的时候才需要通知其他人。
  2. 如果状态没有改变,不进行通知。
  3. 观察者自己也是一个发布面板 – doit(Event, Observer o) ;责任链的递归调用实现。观察者可以通知别的观察者进行观察。标准的责任链模式。

观察者模式分析

1. 定义

定义了对象之间的一对多依赖,这样依赖,当一个对象状态改变时,他的所有依赖都会收到通知并自动更新。

2. 优缺点

  • 实现了观察者和被观察之间的解耦,也就是一个对象和他依赖对象之间的解耦。 (小孩类和爸爸,妈妈,小狗类都独立的)
  • 可以动态增加功能,用于处理对观察者变化的反应。

3. 使用场景

  • 对象之间存在依赖关系
  • 对象之间的通信,结合责任链和命令模式

JDK内置的观察者模式

  • 观察者,根据不同的主题的更新来决定自己是否更新,不能在改变主题的状态了, 否则会死循环。
    • 具体的观察者绑定了某一个主题
    • 观察者不能改变主题的状态,否则会陷入死循环。
  • 被观察者,首先设置改变,其次通知所有的观察者。
改变之后,使用下面的代码进行通知所有的观察者。
setChange();
notifyAllObservers();

  • Observable代码详解


1. 私有的属性: 是否改变,使用vector进行存储对象。
private boolean changed = false;
private Vector<Observer> obs;


2. 增加对象,是一个带锁的实现
    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();			// 首先判断是否为空
        if (!obs.contains(o)) {							// 其次判断是否已经有了,使用set会更快。
            obs.addElement(o);
        }
    }

3. 删除对象,同样是一个带锁的实现
    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

4. 使用对象是经典,解释了为什么需要设置一个change。 -- 为了提醒用户是否真的需要进行。
    
     public void notifyObservers(Object arg) {
        Object[] arrLocal;

        synchronized (this) {					
            if (!changed)
                return;
            arrLocal = obs.toArray();	// 由于调用这个方法,非常的耗时,所以需要用户显示调用设置为true,才进行调用
            clearChanged();
        }			// 没有等待所有的通知完成,而是复制了一份,然后就是线程私有的了,之后再慢慢进行处理,防止锁太长时间。

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

  • 增删都加上锁
  • 复制一份,让线程私有之后,再慢慢进行调用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值