$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
随机推荐
- eclipse 建立maven项目 显示红叉的解决方法
1.建立好之后就会发现项目有红叉. 这时发现查查在main处,打开项目>属性>Java Build Path>source,发现里边有红叉(如下图),这是由于我们的src/main下 ...
- Web Service安全问题,不暴露接口的一种办法
我们在做服务层时,经常会用到Web Service,但是这有个问题,容易被人恶意调用接口. 一种解决办法是自己写个验证SoapHeader,屏蔽接口在网页端调用,但使用这个方法别人还是能看到你的接口有 ...
- Win10系统如何配置Tomcat环境变量
我们知道win10用户在配置Tomcat环境变量的时候,首先需要配置JAVA,这样才能配置Tomcat环境.很多用户并不知道要如何进行配置,下面就给大家介绍win10系统怎样Tomcat环境变量的. ...
- mysql增加自定义函数功能
mysql默认是不能自定义函数的 当create function时 This function has none of DETERMINISTIC, NO SQL, or READS SQL DAT ...
- 求出10000以内所有的完全数-python
题目: 如何用python去求出下一个(大于28的)完全数? (求出10000以内所有的完全数) 分析: 如果一个数恰好等于它的因子之和,则称该数为"完全数".各个小于它的约数(真 ...
- Python简单的线程池
class ThreadPool(object): def __init__(self, max_num=20): # 创建一个队列,队列里最多只能有10个数据 self.queue = queue. ...
- Nginx模块系列之auth_basic模块
1.1 介绍 ngx_http_auth_basic_module模块实现让访问着,只有输入正确的用户密码才允许访问web内容.web上的一些内容不想被其他人知道,但是又想让部分人看到.nginx的h ...
- Ubuntu 下Apache安装和配置2
在Ubuntu上安装Apache,有两种方式:1 使用开发包的打包服务,例如使用apt-get命令:2 从源码构建Apache.本文章将详细描述这两种不同的安装方式. 方法一:使用开发包的打包服务—— ...
- Android无线测试之—UiAutomator工程建立
一.环境要求: 已经搭建好了Android UiAotomator测试环境 二.新建测试工程: 1.打开eclipse,首次打开指定一个工作空间 2.新建一个Java Project,名叫:Demo1 ...
- CodeIgniter框架——函数(时间函数、装载函数)剖析+小知识点
连接数据库: 格式: mysql -h主机地址 -u用户名-p用户密码 数据库的提示符:mysql> 退出数据库: exit(回车) 知识点积累: 1.date_default_timezone ...