$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
随机推荐
- Shiro学习(总结)
声明:本文原文地址:http://www.iteye.com/blogs/subjects/shiro 感谢开涛提供的博文,让我学到了非常多.在这里由衷的感谢你,同一时候我强烈的推荐开涛的博文.他的博 ...
- mongodb性能问题及原理分析
近期忙着把一个项目从MySQL迁移到MongoDB,在导入旧数据的过程中.遇到了些许波折,犯了不少错误,但同一时候也学到了不少知识,遂记录下来. 公司为这个项目专门配备了几台高性能务器,清一色的双路四 ...
- hibernate Session一级缓存 应该注意的地方
Session缓存 Hibernate的一级缓存是由Session提供的,因此它存在于Session的整个生命周期中,当程序调用save()/update()/saveOrupdate()/get() ...
- sqlserver tips
方括号内的表示一个对象名(视图,存储过程,表 等).列名:正常使用时,加不加一样,但是如果对象名是保留字的话,比如cascade,就必须加:不过建议不用保留字作为对象名 if object_id('[ ...
- Error:指向绑定函数的指针只能用于调用函数
a1.determinant; 改为: a1.determinant(); Eigen::MatrixXd a1(,);//ImagePoint a1<<n1,p1,n2,p2; doub ...
- Mac下使用Homebrew 安装MySQL
安装 brew install mysql 卸载 brew uninstall mysql 启动mysql mysql.server start 管理员账户 mysql -uroot
- Unity3d Resources TextAsset 文本
一些小型数据,可以用txt文本作为媒介,进行获取.传输.修改.存储: 比如:User1.2.3.txt,放入 Resources/Data 文件下: 一,Unity3d Resources.Load ...
- 【转】10 个MySQL数据库备份教程推荐
10 个MySQL数据库备份教程推荐 MySQL是动态网站开发中最著名的开源数据库系统.如果你在网站中使用了MySQL,那么你应该定期备份你的数据以防止它丢失. 本文将介绍自动或手动备份MySQL数据 ...
- SQL Server函数
阅读目录 SQL Server函数---Union与Union All的区别 回到顶部 SQL Server函数---Union与Union All的区别 如果我们需要将两个select语句的结果作为 ...
- java内部类详细介绍
0.内部类与一般类有所不同,它是放在外部类的内部即可作为外部类的成员变量,也可放在方法内部作为局部变量,既然是变量,那么它可以用 private static 修饰符修饰,而外部类则不能,这也是内部类 ...