$Java设计模式之——观察者模式(Observer)
(一)观察者模式简介
1、定义:定义对象间一种一对多的依赖关系,一个对象状态发生改变时,所有依赖它的对象都会接到通知并作出相应的响应。
2、应用场景:
(1)GUI系统
(2)订阅-发布系统
(3)事件多级触发场景
(4)当一个对象改变时需要通知其他对象,但不知道有其他对象具体有哪些时
3、UML类图
(二)观察者模式实例
1、假设有个珠宝公司要运送一批钻石,强盗也盯上这批钻石了,准备在运输途中抢劫,而珠宝公司雇佣的保镖要全程对钻石进行保护,警察也派出警车护航,关系如下图:

2、代码如下:
(1)抽象观察者接口:
/**
* 抽象观察者
*
*/ public interface Watcher {
// 对被观察者状态变化做出响应的抽象方法
public void update(String msg);
}
(2)抽象被观察者接口:
/**
* 抽象被观察者
*
*/ public interface Watched {
// 添加观察者
public void addWatcher(Watcher watcher); // 移除观察者
public void removeWatcher(Watcher watcher); // 通知观察者
public void notifyWatchers(String msg);
}
(3)保镖类:
/**
* 保镖类,实现Watcher接口
*
*/ public class Security implements Watcher { @Override
public void update(String msg) {
System.out.println("保镖收到消息:" + msg + "。保镖开始保护!");
} }
(4)警察类:
/**
* 警察类,实现Watcher接口
*
*/ public class Police implements Watcher { @Override
public void update(String msg) {
System.out.println("警察收到消息:" + msg + "。警察开始派警车护航!");
} }
(5)强盗类:
/**
* 强盗类,实现Watcher接口
*
*/ public class Thief implements Watcher { @Override
public void update(String msg) {
System.out.println("收到消息:" + msg + "。强盗准备动手!");
} }
(6)珠宝运输类:
/**
* 具体的被观察者
*
*/ public class Transporter implements Watched { List<Watcher> wathcerList = new ArrayList<Watcher>(); @Override
public void addWatcher(Watcher watcher) {
wathcerList.add(watcher);
} @Override
public void removeWatcher(Watcher watcher) {
wathcerList.remove(watcher);
} @Override
public void notifyWatchers(String msg) {
for (Watcher w : wathcerList) {
w.update(msg);
}
} }
(6)测试类:
public class Test {
public static void main(String[] args) {
Security s = new Security();
Thief t = new Thief();
Police p = new Police();
Transporter transPorter = new Transporter();
transPorter.addWatcher(s);
transPorter.addWatcher(t);
transPorter.addWatcher(p);
transPorter.notifyWatchers("运输车队开始出发了");
transPorter.removeWatcher(t);
transPorter.notifyWatchers("运输车队摆脱了强盗");
}
}
(7)输出结果:
保镖收到消息:运输车队开始出发了。保镖开始保护!
收到消息:运输车队开始出发了。强盗准备动手!
警察收到消息:运输车队开始出发了。警察开始派警车护航!
保镖收到消息:运输车队摆脱了强盗。保镖开始保护!
警察收到消息:运输车队摆脱了强盗。警察开始派警车护航!
Refer:http://blog.csdn.net/jason0539/article/details/45055233
随机推荐
- linux命名空间详解_转
转自: Linux的命名空间详解--Linux进程的管理与调度(二) Linux Namespaces机制提供一种资源隔离方案. PID,IPC,Network等系统资源不再是全局性的,而是属于特定的 ...
- CI框架基本配置/教你学习CI框架codelgniter
CI框架现在中国可以说还是不成熟,不像thinkphp那样有那么多的中文手册,在国内,很多国人英语都很烂,CI现在教程还是不多.大家心里都存在这严重想法 CI 框架现在中国可以说还是不成熟,不像thi ...
- Linux Linux程序练习四
编写两个不同的可执行程序,名称分别为a和b,b为a的子进程. 在a程序中调用open函数打开a.txt文件. 在b程序不可以调用open或者fopen,只允许调用read函数来实现读取a.txt文件. ...
- java 调用cmd命令
public class Port{ public static void main(String[] args) { Runtime runtime=Runtime.getRuntime(); tr ...
- Spring MVC多解析器映射
如果想在spring mvc应用程序中使用多个视图解析器,那么可以使用order属性设置优先级顺序. 以下示例显示如何在Spring Web MVC框架中使用ResourceBundleViewRes ...
- VS+mysql+EF搭建
2016年7月6日更新: vs2010只需要安装mysql的.net connector就可以 vs2012, vs2015都需要安装.net connector + ODBC connector才行 ...
- 七个迹象说明你可能受到APT 攻击
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXF1c2hp/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/d ...
- UESTC 491 Tricks in Bits
Tricks in Bits Time Limit: 1000MS Memory Limit: 65535KB 64bit IO Format: %lld & %llu Submit ...
- 剖析与优化 Go 的 web 应用
https://mp.weixin.qq.com/s/HDsbZLOK3h8-XjejvPH2sA https://studygolang.com/articles/12685
- make tree install 目录树状结构工具安装
http://futeng.iteye.com/blog/2071867 http://zhou123.blog.51cto.com/4355617/1196415 wget ftp://mama.i ...