GoF23种设计模式之行为型模式之观察者模式
一、概述
定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
二、适用性
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面的时候。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象,而且不知道具体有多少对象需要改变的时候。
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁的时候。
三、参与者
1.Subject(目标):目标知道它的观察者。可以有任意多个观察者观察同一个目标。提供注册和删除观察者对象的接口。
2.Observer(观察者):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。
3.ConcreteSubject(具体目标):将有关状态存入各ConcreteObserver对象。当它的状态发生改变时,向它的各个观察者发出通知。
4.ConcreteObserver(具体观察者):维护一个指向ConcreteSubject对象的引用。存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。
四、类图
五、示例
Subject
- package cn.lynn.observer;
- import java.util.ArrayList;
- import java.util.List;
- public abstract class Citizen {
- protected List<Policeman> polices;
- private String action = "normal";
- public String getAction() {
- return action;
- }
- public void setAction(String action) {
- this.action = action;
- }
- public void setPolices() {
- polices = new ArrayList<Policeman>();
- }
- public void register(Policeman police) {
- polices.add(police);
- }
- public void unregister(Policeman police) {
- polices.remove(police);
- }
- public abstract void notify(String action);
- }
Observer
- package cn.lynn.observer;
- public interface Policeman {
- public void setOut(Citizen citizen);
- }
ConcreteSubject
- package cn.lynn.observer;
- public class DongHuCitizen extends Citizen {
- public DongHuCitizen(Policeman police) {
- setPolices();
- register(police);
- }
- @Override
- public void notify(String action) {
- setAction(action);
- for (int i = 0; i < polices.size(); i++) {
- Policeman police = polices.get(i);
- police.setOut(this);
- }
- }
- }
- package cn.lynn.observer;
- public class NanHuCitizen extends Citizen {
- public NanHuCitizen(Policeman police) {
- setPolices();
- register(police);
- }
- @Override
- public void notify(String action) {
- setAction(action);
- for (int i = 0; i < polices.size(); i++) {
- Policeman police = polices.get(i);
- police.setOut(this);
- }
- }
- }
ConcreteObserver
- package cn.lynn.observer;
- public class DongHuPoliceman implements Policeman {
- @Override
- public void setOut(Citizen citizen) {
- String action = citizen.getAction();
- if(action.equals("normal")) {
- System.out.println("行为一切正常");
- } else if(action.equals("unnormal")) {
- System.out.println("有偷窃行为,东湖警察出动!");
- }
- }
- }
- package cn.lynn.observer;
- public class NanHuPoliceman implements Policeman {
- @Override
- public void setOut(Citizen citizen) {
- String action = citizen.getAction();
- if(action.equals("normal")) {
- System.out.println("行为一切正常");
- } else if(action.equals("unnormal")) {
- System.out.println("有抢劫行为,南湖警察出动!");
- }
- }
- }
Client
- package cn.lynn.observer;
- public class Client {
- public static void main(String[] args) {
- Policeman dhPolice = new DongHuPoliceman();
- Policeman nhPolice = new NanHuPoliceman();
- Citizen citizen = new DongHuCitizen(dhPolice);
- citizen.notify("normal");
- citizen.notify("unnormal");
- citizen = new NanHuCitizen(nhPolice);
- citizen.notify("normal");
- citizen.notify("unnormal");
- }
- }
Result
- 行为一切正常
- 有偷窃行为,东湖警察出动!
- 行为一切正常
- 有抢劫行为,南湖警察出动!
GoF23种设计模式之行为型模式之观察者模式的更多相关文章
- GoF23种设计模式之行为型模式之状态模式
一.概述 定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 二.适用性 1.一个对象的行为取决于它的状态,并且它必须在运行时刻 ...
- GoF23种设计模式之行为型模式之策略模式
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 1概述 定义一系列算法,把它们一个个都封装起来,并且让它们可以相互 ...
- GoF23种设计模式之创建型模式之原型模式
一.概述 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 二.适用性 1.当一个系统应该独立于它的产品创建.构成和表示的时候. 2.当要实例化的类是在运行时刻指定的时候,例如:通过动 ...
- GoF23种设计模式之行为型模式之迭代器模式
一.概述 给定一种语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子.二.适用性1.当访问一个聚合对象的内容而无需暴露它的内部表示的时候.2.当对聚合对象的多 ...
- GoF23种设计模式之行为型模式之解释器模式
一.概述 给定一种语言和其文法的一种表示,再定义一个解释器,该解释器使用表示来解释语言中的句子. 二.适用性 当需要解释一种语言,并且可以将该语言中的句子表示 ...
- GoF23种设计模式之行为型模式之访问者模式
概述 表示一个作用于某对象结构中的各元素的操作. 它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 适用性 1.一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依 ...
- GoF23种设计模式之创建型模式之工厂方法模式
一.概述 定义一个用于创建对象的接口,让子类去决定实例化哪个类.工厂方法将一个类的实例化延迟至其子类. 二.适用性 1.当一个类不知道它所必须创建的对象的类的时候. 2.当一个类希望由其子类来指定它所 ...
- GoF23种设计模式之创建型模式之抽象工厂模式
一.概述 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 二.适用性 1.一个系统要独立于它的产品的创建.组合和表示的时候. 2.一个系统要由多个产品系列中的一个来配置的时候. ...
- GoF23种设计模式之创建型模式之建造者模式
一.概述 将一个复杂对象的构建与其表示分离开来,使得同样的构建过程可以创建不同的表示. 二.适用性 1.当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式的时候. 2.当构造过程必须允许 ...
随机推荐
- [NWPU2016][寒假作业][正常版第三组]R&&HDU1240
题意是有个三维的地图,从起点到终点的最短路径.用bfs做,不过这个题坑的地方在于,开三维数组你要搞清楚纬度的关系.a[i][j][h] i是层,j是行,h是列.然后坐标呢,又是列,行,层,所以如果要用 ...
- Spark Mllib里如何建立向量标签(图文详解)
不多说,直接上干货! 注意: val pos = LabeledPoint(1, vd) val neg = LabeledPoint(2, vs) 除了这两种建立向量标签.还可以从数据库中获取固定格 ...
- Linux之shell命令实现-批量去掉文件名中空格,以及批量修改文件名为数字序号文件名
1 shell下批量出去文件名中的空格 执行看现象: 上面的是执行for循环以后看到的: 然而源目录下的文件如下: 这样的话想要cat某个具体文件是拿不到的,所以需要去空格处理: 处理方式有很多:如 ...
- 30个提高Web程序执行效率的好经验
尽量避免使用DOM.当需要反复使用DOM时,先把对DOM的引用存到JavaScript本地变量里再使用.使用设置innerHTML的方法来替换document.createElement/append ...
- c#进行MD5加密方式和解密算法
--------------- 因为加密个解密都需要用到key所有在加密的后需要把key和加密码都存到数据库中 /// <summary> /// 唯一加密方式 /// </summ ...
- js字符串与十六进制之间的转换
在寻找加密解密的时候看到一个方法,代码图片转换.原理为:字符可以转为16进制,与图片RGB的一个R/G/B相对应,即一个像素点可容纳3个字符(注:Canvas的RGBA,透明度A似乎不能使用,使用后, ...
- winform ListView创建columnHeader的方法
using System; using System.Windows.Forms; using System.Drawing; using System.Collections; namespace ...
- UESTC 1307 WINDY数 (数位DP,基础)
题意: windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数.windy想知道,在A和B之间,包括A和B,总共有多少个windy数? 思路: 就是给连续的两 ...
- uva 10328 - Coin Toss 投硬币(dp递推,大数)
题意:抛出n次硬币(有顺序),求至少k个以上的连续正面的情况的种数. 思路:转换成求抛n个硬币,至多k-1个连续的情况种数,用所有可能出现的情况种数减去至多k-1个的情况,就得到答案了.此题涉及大数加 ...
- Android(java)学习笔记127:生成 4种不同权限的文件
1. 首先我们编写一个生成 4种 不同权限的文件的程序案例: (1)首先是activity_main.xml文件: <RelativeLayout xmlns:android="htt ...