设计模式之观察者模式
2015-09-19 17:52
435 查看
在介绍观察者模式之前,我先回忆一下小学时光的趣事,上小学的时候,那时候有自习课,老师就会会办公室休息,然而这是我们最快乐的时光,因为在这个时间里我们就可以玩牌了(play card),因为那时候没有现在科技这么发达,没有智能手机和IPAD等高端移动设备,那时候打扑克就是我们非常喜欢玩的娱乐活动,然而在自习课上打牌是老师和学校里禁止的(这个没听说学校提倡的),每到自习课,我们就想玩扑克,但是不敢大胆的玩啊,因为老师随时都可能来查自习的纪律,没办法,只能轮着看门,看门者的任务就是观察老师什么
时候到来,接着通知打牌的同学,相互合作嘛。
今天,临到赵同学看门,我们几个打牌,自习课上,赵同学自觉的到自己的岗位上,通过窗户望着前方,时刻观察者前方是否有老师出现的动态,我们(钱同学,刘同学)几个就开始高兴的玩牌了
在这里赵同学就是具体主题的通知者,我们就是具体的观察者。
主题通知者的抽象行为:
打牌的人就是具体的观察者,他们最想知道老师是否到来的动态
抽象观察者:
具体的实现(钱同学)
具体的实现(刘同学)
客户端调用逻辑:
结果输出:
这就是一个简单的观察者设计模式的应用,具体的关系类图为:
观察者定义:观察者又叫做发布/订阅模式(publish/subscribe)模式。
观察者定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在发生变化的时候,会通知所有的观察者对象,是他们能够自动更新自己
上面的例子中,赵同学看到老师来了之后,就会通知钱同学和刘同学,接着钱同学和刘同学就会停止打牌的动作,转向学习!!!
几个观察者的名词:
抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。(上面的Subject接口)
抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。(上面的Observer接口)
具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。(上面的上面的SubjectZ类)
具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。(上面的ObserverL和ObserverQ类)
时候到来,接着通知打牌的同学,相互合作嘛。
今天,临到赵同学看门,我们几个打牌,自习课上,赵同学自觉的到自己的岗位上,通过窗户望着前方,时刻观察者前方是否有老师出现的动态,我们(钱同学,刘同学)几个就开始高兴的玩牌了
在这里赵同学就是具体主题的通知者,我们就是具体的观察者。
主题通知者的抽象行为:
package com.panther.dong.designpattern.observer; /** * observer subject(abstract notice) * Created by panther on 15-9-19. */ public interface Subject { public void add(Observer observer); public void drop(Observer observer); public void notice(); }主题通知者的具体实现:
package com.panther.dong.designpattern.observer; import java.util.ArrayList; import java.util.List; /** * zhao负责看门(观察老师的到来)(具体的主题) * Created by panther on 15-9-19. */ public class SubjectZ implements Subject { private List<Observer> observerList = new ArrayList<>(); //任何一个想打牌的同学都和zhao说,老师来了通知他 @Override public void add(Observer observer) { observerList.add(observer); } //其中一个同学和zhao关系不好,zhao不通知他 @Override public void drop(Observer observer) { observerList.remove(observer); } @Override public void notice() { for (Observer observer : observerList) { observer.update(); } } }
打牌的人就是具体的观察者,他们最想知道老师是否到来的动态
抽象观察者:
package com.panther.dong.designpattern.observer; /** * 抽象的观察者 * Created by panther on 15-9-19. */ public interface Observer { public void update(); }
具体的实现(钱同学)
package com.panther.dong.designpattern.observer; /** * 具体的观察者 * Created by panther on 15-9-19. */ public class ObserverQ implements Observer{ @Override public void update() { System.out.println("钱,拿出数学题目做题"); } }
具体的实现(刘同学)
package com.panther.dong.designpattern.observer; /** * 具体的观察者 * Created by panther on 15-9-19. */ public class ObserverL implements Observer { @Override public void update() { System.out.println("刘,拿出课本来读书"); } }
客户端调用逻辑:
package com.panther.dong.designpattern.observer; /** * client implement * Created by panther on 15-9-19. */ public class Client { public static void main(String[] args) { System.out.println("----------------------------------"); //赵看门 Subject subjectZ = new SubjectZ(); ObserverL observerL = new ObserverL(); ObserverQ observerQ = new ObserverQ(); //刘和钱打牌,告诉赵老师来了叫他们 subjectZ.add(observerL); subjectZ.add(observerQ); //老师来了,刘和钱收到赵的通知 subjectZ.notice(); System.out.println("----------------------------------------"); //假设赵和刘关系不好,老师来了赵通知钱,但是不通知刘 subjectZ.drop(observerL); subjectZ.notice();//只有钱收到通知,刘收不到通知 System.out.println("------------------------------------------"); } }
结果输出:
这就是一个简单的观察者设计模式的应用,具体的关系类图为:
观察者定义:观察者又叫做发布/订阅模式(publish/subscribe)模式。
观察者定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在发生变化的时候,会通知所有的观察者对象,是他们能够自动更新自己
上面的例子中,赵同学看到老师来了之后,就会通知钱同学和刘同学,接着钱同学和刘同学就会停止打牌的动作,转向学习!!!
几个观察者的名词:
抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。(上面的Subject接口)
抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。(上面的Observer接口)
具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。(上面的上面的SubjectZ类)
具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。(上面的ObserverL和ObserverQ类)
相关文章推荐
- 2015.9.19 第十二堂 NSString
- USACO 1.4 The Clocks (暴力枚举)
- Cocos2d-x 周边工具 之 BMFont
- PHP中SQL注入解析
- 50. 别逗我了,好吧!
- A013-animator资源
- HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)
- 一维数组的探索
- WordPress性能优化
- Linux在iptables教程基本应用防火墙
- Redis配置文件解析
- UVa 11732 - strcmp() Anyone?
- 改变unity场景的图片比例保存到xml当中
- hdu 2161 Primes
- 数组名和指针的区别
- 01机房可行性研究报告
- win8.1-进入测试模式-调试模式
- 1018:Communication System
- 【日常学习】【倍增LCA】codevs2370 小机房的树题解
- ubuntu安装deb文件时,缺少的依赖的下载网址