观察者模式(发布订阅模式)

1. 观察者模式定义

 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
(Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notifited and updated automatically.)

其实就是众多观察者在观察,一旦被观察者发生了某种改变,将立刻触发去通知观察者们,各观察者会根据自己的情况作出不同反应。

2. 观察者模式通用类图

![这里写图片描述](https://img-blog.csdn.net/20170920193124257?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQXNoZXMxOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 

3. 观察者角色说明

(1)Subject被观察者
        定义被观察者必须实现的职责,它必须能够动态的增加、取消观察者。(一般仅仅完成作为被观察者必须实现的职责,管理观察者并通知观察者)

(2)Observer观察者
        观察者接受到消息后,即进行update(更新方法)操作,对接收到的信息进行处理

(3)ConcreteSubject具体的被观察者
        定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知

(4)ConcreteObserver具体的观察者
        每个观察在接收到消息后的处理反应是不同的,各个观察者有自己的处理逻辑。

总结来就是敌动我动,敌不动我也不动!!!

4. 好玩的代码实现


a、被观察者接口

/**
 * 被观察者接口
 */
public interface IHanFeiZi { 
    /**
     * 韩非子也是人,也要吃早饭
     */
    public void haveBreakfast(); 
    /**
     * 韩非子也是人,也是要娱乐的
     */
    public void haveFun();
}

b、具体的被观察者

/**
 * 具体的被观察者,对接口进行扩充
 * 升级:通过聚集方式的被观察者
 */
public class HanFeiZi extends Observable implements IHanFeiZi {

    /**
     * 韩非子要吃饭了
     */
    @Override
    public void haveBreakfast() {
        System.out.println("韩非子开始吃饭了。。。");
        //通知所有的观察者
        super.setChanged();
        super.notifyObservers("韩非子在吃饭");
    }

    /**
     * 韩非子开始娱乐了 
     */
    @Override
    public void haveFun() {
        System.out.println("韩非子开始娱乐了。。。");
        //通知所有的观察者
        super.setChanged();
        super.notifyObservers("韩非子在娱乐");
    }
}

c、定义观察者,注意,这里的Observer是一个(abstract interface)抽象接口哦!!!!

/*** Eclipse Class Decompiler plugin, copyright (c) 2012 Chao Chen ([email protected]) ***/
package java.util;

public abstract interface Observer {
    public abstract void update(Observable paramObservable, Object paramObject);
}
/** 
 * 李斯这类人很简单,一发现自己观察的对象发生了变化,自己立刻也要行动起来
 */
public class Liusi implements Observer {

    /**
     * 首先李斯是个观察者,一旦韩非子有活动,他就知道,他就要向老板汇报了
     */
    @Override
    public void update(Observable observable, Object obj) {
        System.out.println("刘斯: 观察到韩非子活动,开始自己的活动。。。");
        this.cry(obj.toString());
        System.out.println("刘斯: 最后可能气死了。。。\n");
    }

    /**
     * 我不是秦国的,韩非子有变化我就痛苦
     * @param reportContext
     */
    private void cry(String reportContext) {
        System.out.println("刘斯:因为  ====> " + reportContext + "所以我很痛苦。。。");
    }
}

4、我们需要定义不同的观察者,

/**
 * 李斯这类人很简单,一发现自己观察的对象发生了变化,自己立刻也要行动起来
 */
public class Lisi implements Observer {

    /**
     * 首先李斯是个观察者,一旦韩非子有活动,他就知道,他就要向老板汇报了
     */
    @Override
    public void update(Observable observable, Object obj) {
        System.out.println("李斯: 观察到韩非子活动,开始向老板汇报了。。。");
        this.reportToQinShiHuang(obj.toString());   //原来是传过来一个字符串
        System.out.println("李斯: 汇报完毕。。。\n");
    }

    /**
     * 汇报给秦始皇
     * @param reportContext
     */
    private void reportToQinShiHuang(String reportContext) {
        System.out.println("李斯: 报告,报告,秦老板,韩非子有活动了  ====> " + reportContext);
    }
}

5、多个观察者体会当被观察者发生变动的时候,我们的观察者们作出的不同的反应。

/**
 * 
 * @author Ashes
 * @Description 
 * 2017年8月24日
 * 
 * 李斯这类人很简单,一发现自己观察的对象发生了变化,自己立刻也要行动起来
 */
public class Lvsi implements Observer {

    /**
     * 首先李斯是个观察者,一旦韩非子有活动,他就知道,他就要向老板汇报了
     */
    @Override
    public void update(Observable observable, Object obj) {
        System.out.println("吕斯: 观察到韩非子活动,开始自己的活动。。。");
        this.happy(obj.toString());
        System.out.println("吕斯: 最后还是很开心。。。\n");
    }

    /**
     * 我不是秦国的,韩非子有变化我就快乐
     * @param reportContext
     */
    private void happy(String reportContext) {
        System.out.println("吕斯:因为  ====> " + reportContext + "所以我很快乐。。。");
    }
}

6、测试一下我们的代码

/**
 * 符合开闭原则,类间解耦
 */
public class Client {
    public static void main(String[] args) throws InterruptedException {
        //定义出三个观察者
        Observer lisiObserver = new Lisi();
        Observer liusiObserver = new Liusi();
        Observer lvsiObserver = new Lvsi();
        //定义出韩非子
        HanFeiZi hanFeiZi = new HanFeiZi();

        hanFeiZi.addObserver(lisiObserver);
        hanFeiZi.addObserver(liusiObserver);
        hanFeiZi.addObserver(lvsiObserver);

        hanFeiZi.haveBreakfast();
        hanFeiZi.haveFun();
    }
}

7、 大家有没有得到这样的效果嘞

李斯: 观察到韩非子活动,开始向老板汇报了。。。
李斯: 报告,报告,秦老板,韩非子有活动了  ====> 韩非子在吃饭
李斯: 汇报完毕。。。

韩非子开始娱乐了。。。
吕斯: 观察到韩非子活动,开始自己的活动。。。
吕斯:因为  ====> 韩非子在娱乐所以我很快乐。。。
吕斯: 最后还是很开心。。。

刘斯: 观察到韩非子活动,开始自己的活动。。。
刘斯:因为  ====> 韩非子在娱乐所以我很痛苦。。。
刘斯: 最后可能气死了。。。

李斯: 观察到韩非子活动,开始向老板汇报了。。。
李斯: 报告,报告,秦老板,韩非子有活动了  ====> 韩非子在娱乐
李斯: 汇报完毕。。。

参考学习《设计模式之禅》完成

猜你喜欢

转载自blog.csdn.net/Ashes18/article/details/78044688