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、 大家有没有得到这样的效果嘞
李斯: 观察到韩非子活动,开始向老板汇报了。。。
李斯: 报告,报告,秦老板,韩非子有活动了 ====> 韩非子在吃饭
李斯: 汇报完毕。。。
韩非子开始娱乐了。。。
吕斯: 观察到韩非子活动,开始自己的活动。。。
吕斯:因为 ====> 韩非子在娱乐所以我很快乐。。。
吕斯: 最后还是很开心。。。
刘斯: 观察到韩非子活动,开始自己的活动。。。
刘斯:因为 ====> 韩非子在娱乐所以我很痛苦。。。
刘斯: 最后可能气死了。。。
李斯: 观察到韩非子活动,开始向老板汇报了。。。
李斯: 报告,报告,秦老板,韩非子有活动了 ====> 韩非子在娱乐
李斯: 汇报完毕。。。
参考学习《设计模式之禅》完成