设计模式-观察者模式 发布/订阅模式

代码

观察者接口

public interface IHanFeiZi{// 当吃早饭时public void havBreakFast();// 进行娱乐活动时public void haveFun();
}

具体的被观察者

public class HanFeiZi implements IHanFeiZi{`// 根据是否在吃饭,作为监控的标准private boolean isHavingBreakfast = false;// 判断是否在娱乐private boolean isHavingFun = false;// 当吃饭的时候public void haveBreakfast(){System.out.println("吃饭了");this.isHavingBreakfast = true;}// 当开始娱乐的时候public void haveFun(){System.out.println("开始娱乐");this.isHavingFun = true;}// 下方位get/set省去
}

观察者

public interface ILiSi{// 发行有人有动静,进行行动public void update(String context);
}
public class LiSi implements ILiSi{// 首先他为一个观察者public void update(String str){System.out.println("观察到某人活动,进行汇报");this.reportToQinShiHuang(str); // 调用汇报方法System.out.println("汇报完毕");}// 进行汇报、private void reportToQinShiHuang(String reportContext){System.out.println("进行汇报");}
}

最后定义中间

class Spy extends Thread{private HanFeiZi hanFeiZi;private LiSi liSi;private String type;// 通过构造函数注入,显示将要监控谁public Spy(HanFeiZi _hanFeiZi, LiSi _liSi, String _type){this.hanFeiZi = _hanFeiZi;this.liSi = _liSi;this.type = _type;}@Overridepublic void run(){while(true){if(this.type.equals("breakfast")){   // 监控是否吃早餐// 如果在吃饭,则通知if(this.hanFeiZi.isHavingBreakfast()){this.liSi.update("在吃饭");// 重置状态,继续监控this.hanFeiZi.setHavingBreakfast(false);}}else{ // 判断是否在娱乐if(this.hanFeiZi.isHavingFun()){this.liSi.update("在娱乐");this.hanFeiZi.setHavingFun(false);}}}}
}

场景类

public class Client{public static void main(String[] args) throws interruptedException {// 定义两个人LiSi liSi = new LiSi();HanFeiZi hanFeiZi = new HanFeiZi();// 观察早餐Spy watchBreakfast = new Spy(hanFeiZi, lisi, "breakfast");watchBreak.start();  // 启动线程、// 继续查看都干什么Thread.sleep(1000);hanFeiZi.haveBreakfast(); // 开始吃饭// 如果娱乐Thread.sleep(1000);hanFeiZi.haveFun();    // 查看情况}
}

修改

由于上面使用了一个死循环,会导致出现问题。并且由于多线程的缘故,会导致数据的污染问题,根本无法使用。
修改如下

public class HanFeiZi implements IHanFeiZi{// 声明李private ILiSi lisi = new LiSi();// 当吃饭的时候public void hanveBreakfast(){System.out.println("吃饭开始");this.liSi.update("吃饭了");}// 当娱乐的时候public void haveFun(){System.out.println("开始娱乐");this.liSi.update("在娱乐");}
}

最后书写场景类

public class Client{public static void main(String[] args){// 定义出韩HanFeiZi hanFeiZi = new HanFeiZi();// 继续查看韩在干什么hanFeiZi.haveBreakfast();// 当其娱乐hanFeiZi.haveFun();}
}

继续改进

如果这样聚合,如果有一堆人需要监控被观察者,这样不行,不能一个监控一个,如果此时要修改其他的监控内容,那么都要修改,违反开闭原则

开闭原则 对扩展开放,对修改关闭

那么,将被观察者的自身活动定义一个接口,被观察者定义接口,在统一的类HanFeiZi中实现该接口,对于观察者来说,定义一个观察者的接口,然后多名观察者分别实现该类
被观察者

public interface Observable {// 增加一个观察者public void addObserver(Observer observer);// 删除一个观察者public void deleteObserver(Observer observer);// 当发生动作的时候,通知观察者public void notifyObservers(String context);
}

上方是一个统一的观察者接口,所有的观察者都能实现这个接口。继续查看被观察者

public class HanFeiZi implements Observalbe, IHanFeiZi{// 定义数组,用于保存观察者private ArrayList observerList = new ArrayList();// 增加观察者public void addObserver(Observer observer){this.observerList.add(observer);}// 删除观察者public void deleteObserver(Observer observer){this.observerList.remove(observer);}// 通知所有的观察者public void notifyObservers(String context){for(Observer observer:observerList){observer.update(context);}}// 当要吃饭了public void haveBreakfast(){System.out.println("吃饭");// 通知观察者this.notifyObservers("在吃饭");}// 开始娱乐public void haveFun(){System.out.println("开始娱乐");this.notifyObservers("在娱乐");}
}
// 书写观察者接口
public interface Observer{// 发现动静,进行行动poublic void update(String context);
}
// 书写三个观察者,只需要实现观察者的接口即可
public class LiSi implements Observer{// 首先要为观察者public void update(String str){System.out.println("开始活动了");// 汇报this.reportToQinShiHuang(str);System.out.println("汇报完毕");}// 汇报private void reportToQinShiHuang(String reportContext){System.out.println("进行汇报");}
}

同理,需要观察者直接实现接口即可。

场景类

public class Client{public static void main(String[] args){// 定义三个观察者Observer liSi = new LiSi();Observer wangSi = new WangSi();Observer liuSi = new LiuSi();// 定义被观察的HanFeiZi hanFeiZi = new HanFeiZi();// 当三个人观察韩的时候hanFeiZi.addObserver(liSi);hanFeiZi.addObserver(wangSi);hanFeiZi.addObserver(liuSi);// 然后查看在干什么hanFeiZi.haveBreakfast();}
}

这样就完成了观察者模式,当被观察的发生改变的时候,通知被通过构造方法注入的观察者,此观察者保存在动态数组中,然后当被观察者发生改变的时候,只需要使用循环通知保存在数组中的观察者即可。

这里有一个接口,如果有多个观察者,可以定义一个接口,只需要实现这个即可即可,声明一个接口,然后使用不同的实例,对接口进行实例化。即可。

订阅/发布模型

观察者模式同时也叫发布订阅模型,即,消息驱动,消息发布着发布一个消息,然后通过容器实现对订阅者的进行发布,达到通知订阅者的目的,并且订阅者动态的保存在数组中。

其他

博客 www.iming.info

公众号

设计模式-观察者模式 发布/订阅模式相关推荐

  1. python 设计模式 观察者模式(发布订阅模式)

    发布订阅模式 观察者模式应用比较广泛,又被称为"发布-订阅"模式.它用来定义对象间一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新. 问题1 ...

  2. 每日学习一个设计模式--观察者模式(发布-订阅模式)

    定义 观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.这种模式有时又称作发布-订阅模式.模型-视图模式,它 ...

  3. 设计模式 | 观察者模式/发布-订阅模式(observer/publish-subscribe)

    定义: 定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 结构:(书中图,侵删) 一个抽象的观察者接口, ...

  4. JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

  5. 从东京奥运会看js设计模式之发布订阅模式

    开篇废话:本篇文章介绍发布-订阅模式,想必很多人听说过有一种观察者模式,网上既有资料说这是两种不同的设计模式,也有说这是一种模式,我倾向于认同他们是同一种设计模式.不必过于纠结 开篇楔子:东京奥运会已 ...

  6. JavaScript 设计模式之发布-订阅模式(上)

    什么是发布订阅模式? 发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在JavaScript开发中,我们一般用事件模型来替 ...

  7. c#事件的发布-订阅模型_C# 委托和事件 与 观察者模式(发布-订阅模式)讲解 by天命...

    使用面向对象的思想 用c#控制台代码模拟猫抓老鼠 我们先来分析一下猫抓老鼠的过程 1.猫叫了 2.所有老鼠听到叫声,知道是哪只猫来了 3.老鼠们逃跑,边逃边喊:"xx猫来了,快跑啊!我是老鼠 ...

  8. 【设计模式】692- TypeScript 设计模式之发布-订阅模式

    前言 在之前两篇自测清单中,和大家分享了很多 JavaScript 基础知识,大家可以一起再回顾下~ 本文是我在我们团队内部"「现代 JavaScript 突击队」"分享的一篇内容 ...

  9. 游戏服务器架构-设计模式之发布订阅模式

    发布订阅模式场景 熟悉消息中间件的同学应该对发布/订阅模式(Publish Subscribe Pattern)并不陌生.即使你不了解消息中间件,那么在平时生活中发布/订阅模式也是非常常见的场景. 比 ...

最新文章

  1. 在内网中使用maven_maven构建docker镜像三部曲之三:推送到远程仓库(内网和阿里云)-Go语言中文社区...
  2. delphi编程创建桌面快捷方式
  3. Java黑皮书课后题第8章:8.9(井字游戏)玩家使用各自标志标记3*3网格中的某个空格,当一个玩家在网格的水平、垂直或对角线方向标记了三个相同的标记时,游戏结束,该玩家获胜。创建一个玩井字游戏的程序
  4. 30kJava程序员升为全栈架构师的晋升之路
  5. HDOJ 4876 ZCC loves cards
  6. iframe在ipad safari的显示
  7. 面向对象软件开发代码结构(1)
  8. Apache 配置:是否显示文件列表
  9. RiPro小八子主题V1.5.5美化版+优惠码折扣+工单系统+任务系统
  10. 终端输入vue ui没反应---使用vue ui出现的四个问题
  11. linux socket编程:简易客户端与服务端
  12. 安卓手机怎么彻底清理手机内存_手机内存难清理?试试直接删掉这3个文件夹...
  13. SQL必知必会【极客时间笔记】
  14. 《硅谷钢铁侠》---- 读书笔记
  15. 区块链开发(四)区块链技术详解PPT
  16. 伊诺伊香槟分校计算机世界排名,伊利诺伊大学香槟分校世界排名及专业排名汇总(QS世界大学排名版)...
  17. vue将文件图片批量打包下载zip
  18. Candence PCB Allegro④约束规则管理与布线
  19. uniapp h5 海报
  20. 3626 三元一次方程(枚举)

热门文章

  1. Kotlin 学习笔记(七)—— Kotlin类与对象之属性与字段
  2. web.xml中webAppRootKey
  3. 读书笔记2013第16本:《删除:大数据取舍之道》
  4. 多线程编程-工具篇-BlockingQueue
  5. 算法心得1:由$nlogn$复杂度的LIS算法引起的思考
  6. The current branch is not configured for pull N...
  7. 寻宝处理器的引人入胜之旅——《大话处理器》新书出炉
  8. httpModule一些细节
  9. PowerDesigner(二)-项目和框架矩阵
  10. swagger: fetching resource list: http://localhost:8080/template/v2/api-docs?group=springboot-templat