观察者模式简介
定义
观察者模式是一种一对多的依赖关系,每当一个对象改变状态时,则所有依赖于它的对象都会得到通知并自动更新。
可以这样理解,一条绳上的蚂蚱,一荣俱荣,一损俱损,类似这样的感觉。
例子
近日,世界杯正在火热的进行中,幸好赛程不是在白天,大部分安排在夜间23点到2点间,避免了上班偷偷摸摸看世界杯,生怕被领导发现……可以熬夜也是一种痛苦啊……但NBA季后赛和总决赛就没有这么好了,好多赛程都在平时上班时间内进行,今年是火箭近些年最有希望夺冠的一年,当火箭在西部决赛拿到赛点的时候,感觉离冠军越来越近了,可是最终还是被勇士翻盘了;在这期间为了看比赛,上班总是在不断切换屏幕,怕领导突然进入办公室被发现,可就惨了。
由于跟前台的妹子平时聊的还比较好,事先跟前台妹子通通气了,如果领导来了,马上发震动消息通知下,我就好愉快的切换电脑屏幕,进入工作状态,哈哈……
上面的例子就是典型的观察者模式的样本,如果其他人也有同样的需求,那怎么办了?
- 某某 先找到前台妹子
- 再跟前台妹子通好气来,类似于注册登记
- 等领导来了,就立马发消息通知大家
- 大家收到消息后,马上切换屏幕,进入工作状态。
接下来使用观察者模式实现:
1、哪些同事需要无找前台妹子。
/**
*
* @author 13480
* 哪些同事需要去前台妹子那登记,这些人都有共同的特征,就是切换更新屏幕。
*
*/
public interface Colleague {
/**
* 更新切换屏幕
* @param msg 收到前台妹子发来的消息内容
*/
void updateScreen(String msg);
}
-------------------具体同事的名字-------------------
public class ITColleague implements Colleague{
private String name;
public ITColleague(String name) {
super();
this.name=name;
}
//收到消息后的动作
@Override
public void updateScreen(String msg) {
System.out.println(name+"收到前台妹子发来的消息了,马上切换屏幕");
}
}
2、先去前台找到妹子(Girl)
/**
*
* @author 13480
* 前台有很多妹子,但都有共同的特点,权利很大,有权选择通知谁,千万别随意得罪妹子哦
* 有添加、删除、通知等权利。
*/
public interface Girl {
/**
* 在前台在登记的方法
* @param observer 登记人的名字
*/
void attach(Colleague observer);
/**
* 删除某人,不通知他
* @param observer 被删除人的名字
*/
void delete(Colleague observer);
/**
* 妹子给每位同事发消息
* @param msg 消息的具体内容
*/
void sendMessage(String msg);
}
-----------------------具体妹子的名字----------------
/**
*
* @author 13480
* 具体到哪一个妹子,选瑶瑶妹子吧,人比较漂亮。
* 瑶瑶那有一张表,记录了所有登记过的同事名单,在代码上用集合保存
*/
public class YaoYaoGirl implements Girl{
private List<Colleague> mList=new ArrayList<Colleague>();
@Override
public void attach(Colleague observer) {
mList.add(observer);
}
@Override
public void delete(Colleague observer) {
mList.remove(observer);
}
@Override
public void sendMessage(String msg) {
for (int i = 0; i < mList.size(); i++) {
Colleague colleague = mList.get(i);
colleague.updateScreen(msg);
}
}
}
3、领导来,瑶瑶妹子发消息通知大家,收到的同事做动作
public class ObserverTest {
public static void main(String[] args) {
//找到前台瑶瑶妹子
YaoYaoGirl yaoYaoGirl = new YaoYaoGirl();
//具体需要通知的同事
Colleague colleague1 = new ITColleague("牛哥");
Colleague colleague2 = new ITColleague("凯帆");
Colleague colleague3 = new ITColleague("华哥");
//具体同事到瑶瑶妹子那登记
yaoYaoGirl.attach(colleague1);
yaoYaoGirl.attach(colleague2);
yaoYaoGirl.attach(colleague3);
//领导来了,瑶瑶妹子发震动消息
yaoYaoGirl.sendMessage("领导来了");
}
}
输出结果:
牛哥收到前台妹子发来的消息了,马上切换屏幕
凯帆收到前台妹子发来的消息了,马上切换屏幕
华哥收到前台妹子发来的消息了,马上切换屏幕
这就是整个观察者模式的实现,下面用UML类图体现上面的实现:
UML结构图
角色介绍:
- Colleague:抽象观察者(Observer),定义了接口,定义了更新自己状态的方法。
- ITColleague:具体观察者(ConcrereObserver),实现抽象观察者所有方法,收到被观察者发送的消息时更新自己的状态。
- Girl:抽象被观察者(Subject),定义了接口,定义了增加、删除、发送消息方法。
- YaoYaoGirl:具体被观察者(ConcrereSubject),实现抽象被观察者所有方法,同时用集合保存所有注册的具体观察者对象,最后发送消息通知具体观察者更新状态。
使用场景
优点及使用场景:
- 降低了观察者与被观察者将耦合度,有利于业务扩展(类似ListView中notifyDataSetChanged),方便实现一套事件触发机制事件(类似于事件总线EventBus框架)。
缺点:
- 由于观察者对象是用数组保存的,一般是按顺序执行,如果其中某个观察者对象出现卡顿,后面的将会受到影响。