一:身边的观察者模式

传统的报纸和杂志的订阅就是一种观察者模式:

报社的业务就是出版报纸

向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸来。

当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来。

只要报社还在运营,就会有人(或单位)向他们订阅报纸或取消订阅报纸。

二:什么是观察者模式

由报社和订报人的关系可以看出:出版者+订阅者 = 观察者模式

观察者模式:定义了对象之间的一对多依赖,当一个对象改变状态时,它所有的依赖者都会收到通知并自动更新。

定义观察者模式

《interface》Subject:主题接口,对象使用此接口注册为观察者,或者把自己从观察者中删除。

ConcreteSubject:具体主题,实现了主题接口,除了注册和撤销方法之外,具体主题还实现了notifyObservers(),此方法用于在状态改变时更新所有当前观察者。

《interface》Observer:观察者接口,这个接口只有update()一个方法,当主题状态改变时它被调用。

Observer:具体观察者,必须注册具体主题,以便接受更新。

当两个对象之间松耦合,他们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象涉及,让主题和观察者之间松耦合

三:下面我拿lol游戏中的实景来写段代码,体现游戏中的观察者模式(为了更好的理解,我们先不用java内置支持):

主人公:我方中路(solo无解的流浪法师),下路(寄托希望的寒冰箭手),上路(万年蹲的德玛西亚),野区(打野的木木)。

对方中路(高出我们战斗力5000的大神阿卡丽)。

场景:————————————————出门前——————————————————————

寒冰:流浪,对面阿卡丽有点牛逼,她如果中路消失的话你提醒下我啊![此时,寒冰就成了观察者(observe),而流浪则是主题(subject),寒冰向他注册了(registerObserver()),希望阿卡丽gank的时候提醒下自己(notifyObservers())]

流浪:OK![此时,流浪的观察者队列里面已经添加了寒冰]

德玛西亚:¥%¥&%&(……¥%¥  [对流浪说了同样的话,又增加了一个观察者]。

木木:我打野,我不关心  [那他现在就是个路人甲。。]

让我们先来实现主题的接口类:

1 public interfaceSubject {2

3 public void registerObserver(Observer o);//注册观察者

4

5 public void removeObserver(Observer o);//解除观察者

6

7 public void notifyObservers();//通知观察者

8

9 }

观察者的接口类:

1 public interfaceObserver {2

3 public void update(String alarm);//当被观察者发生变化时,调用观察者的update,把alarm发给观察者。

4

5 public void action();//观察者的行为

6

7 }

流浪:

1 importjava.util.ArrayList;2

3

4 public class RogueMage implementsSubject {5

6 private ArrayListobservers;7 private boolean isMiss = false;//阿卡丽是否消失

8 public static String ALARM = "我了个去,阿卡丽不见了!--本条消息来自流浪法师";9 public static String SAFE = "她在线上呢!--本条消息来自流浪法师";10 public intlevel;11

12 publicRogueMage() {13 observers = new ArrayList();14 }15

16 @Override17 public voidregisterObserver(Observer o) {18 //TODO Auto-generated method stub

19 if(observers.contains(o) == false){20 observers.add(o);21 }22 }23

24 @Override25 public voidremoveObserver(Observer o) {26 //TODO Auto-generated method stub

27 if(observers.contains(o) == true){28 observers.remove(o);29 }30 }31

32 @Override33 public voidnotifyObservers() {34 //TODO Auto-generated method stub

35 for(int i = 0;i < observers.size();i++){36 observers.get(i).update(ALARM);37 }38 }39

40 private void isMissing(){//阿卡丽消失了

41 System.out.println(ALARM);42 System.out.println();43 System.out.println("-----------------------------------");44 notifyObservers();45 }46

47 public void setMissingState(boolean isMiss){//设置阿卡丽状态

48 this.isMiss =isMiss;49 if(isMiss == true){50 isMissing();51 }52 }53

54 public int getLevel(){//获取阿卡丽等级

55 returnlevel;56 }57

58 public void setLevel(int level){//设置阿卡丽等级

59 this.level =level;60 }61 }

寒冰:

1 public class FrostArcher implementsObserver{2

3 privateSubject subject;4

5 publicFrostArcher(Subject subject) {6 this.subject =subject;7 subject.registerObserver(this);8 }9

10 @Override11 public voidupdate(String alarm) {12 //TODO Auto-generated method stub

13 if(alarm.equals(RogueMage.ALARM)){14 action();15 }16 }17

18 @Override19 public voidaction() {20 //TODO Auto-generated method stub

21 System.out.println("寒冰射手:好可怕,我还是缩塔好了。");22 }23

24

25 }

德玛西亚:

1 public class Garen implementsObserver {2 privateSubject subject;3

4 publicGaren(Subject subject) {5 this.subject =subject;6 subject.registerObserver(this);7 }8

9 @Override10 public voidupdate(String alarm) {11 //TODO Auto-generated method stub

12 if(alarm.equals(RogueMage.ALARM)){13 action();14 }15 }16

17 @Override18 public voidaction() {19 //TODO Auto-generated method stub

20 System.out.println("德玛西亚:我在草丛,她看不见我看不见我~");21 }22

23 }

OK!战斗前准备就绪,全军偷鸡!

1 public classBegin {2

3 public static voidmain(String[] agrs){4

5 //战斗开始,人物诞生6 //寒冰和德玛西亚跟流浪法师打招呼,要求阿卡丽消失通知自己

7 RogueMage rogueMage = newRogueMage();8 FrostArcher frostArcher = newFrostArcher(rogueMage);9 Garen garen = newGaren(rogueMage);10

11 System.out.println("----------战斗开始10分钟,流浪法师发现阿卡丽消失-------------");12 rogueMage.setMissingState(true);//流浪法师发现阿卡丽消失。

13

14 }15 }

结果:

得益于我们简单的观察者模式,阿卡丽第一次gank没有成功,寒冰和德玛西亚他们都躲得远远的,是不是很开心~。

有时候并不是所有的队友会要求别人积极的告诉你关注的消息(推送消息),而且所有人关注的东西都不一样,比如木木,他不怕阿卡丽gank。相反,由于自信,他希望阿卡丽再次gank的时候,自己能从流浪那获取阿卡丽的等级帮助队友反杀,所以我们只好来让木木获得消息(拉取消息)。

木木:

1 public class Sadmummy implementsObserver {2

3 privateSubject subject;4 privateRogueMage rogue;5

6

7 publicSadmummy(Subject subject) {8 this.subject =subject;9 if(subject instanceofRogueMage){10 rogue =(RogueMage)subject;11 }12 subject.registerObserver(this);13 }14

15

16

17 @Override18 public voidupdate(String alarm) {19 //TODO Auto-generated method stub

20 if(alarm.equals(RogueMage.ALARM)){21 action();22 }23 }24

25 @Override26 public voidaction() {27 //TODO Auto-generated method stub

28 int level =rogue.getLevel();29 System.out.println("木木:阿卡丽才"+level+"级,看我去啪啪啪了她");30 }31

32 }

继续玩:

1 public classBegin {2

3 public static voidmain(String[] agrs){4

5 //战斗开始,人物诞生6 //寒冰和德玛西亚跟流浪法师打招呼,要求阿卡丽消失通知自己7 //木木和流浪法师打招呼,要求阿卡丽消失的时候也通知自己

8 RogueMage rogueMage = newRogueMage();9 FrostArcher frostArcher = newFrostArcher(rogueMage);10 Garen garen = newGaren(rogueMage);11

12 System.out.println("----------战斗开始10分钟,流浪法师发现阿卡丽消失-------------");13 rogueMage.setMissingState(true);//流浪法师发现阿卡丽消失。

14

15

16

17 Sadmummy mumumy = newSadmummy(rogueMage);18 System.out.println();19 System.out.println();20 System.out.println("-----------战斗开始20分钟,流浪法师发现阿卡丽再次消失----------");21 rogueMage.setLevel(10);//因为木木要知道阿卡丽等级

22 rogueMage.setMissingState(true);//流浪法师发现阿卡丽消失

23

24

25

26 }27 }

结果:

不出意料,由于用了我们的观察者模式,这次阿卡丽不但没有杀人成功还丢了firstBlood,高手怎么能忍受这耻辱,果断退出了游戏,小伙伴们取得了胜利,喜大普奔啊~

四:代码中的观察者

比如button中的listener,当button注册了监听的时候,当界面观察到button被点击则会通知button调用onclick()的方法;

android中的 BroadcastReceiver注册了监听intent,当系统收到intent符合条件时会通知BroadcastReceiver调用onreceive();

MVC--模型(model)-视图(view)-控制器(controller),典型的观察者模式。

OO原则:

封装变化

多用组合,少用继承

针对接口编程,不针对实现编程

为交互对象之间的松耦合设计而努力

lol java_浅谈设计模式(java)——从lol来看观察者模式相关推荐

  1. 浅谈对java编程思想的理解

    浅谈对java编程思想的理解 刚从学校毕业的时候,对于这种概念的理解少之又少 ,只是单纯的从事编码工作,理解也只是停留在对java基本概念的使用上,很局限!随后工作了快三年的时间里,自己不断的理解这种 ...

  2. 解耦 多态性 java_Java的多态浅谈,Java多态浅谈网站安全分享!

    Java的多态浅谈概述Java的四大基本特性:抽象,封装,继承和多态.其中,抽象,封装,继承可以说多态的基础,而多态是封装,继承的具体表现.如果非要用专业术语来描述什么是多态的话 多态是指程序中定义的 ...

  3. file相对路径java_浅谈java 中文件的读取File、以及相对路径的问题

    一.对于java项目中文件的读取 1.使用system 或是 系统的properties对象 ①直接是使用 string relativelypath=system.getproperty(" ...

  4. 后端语言除了java_浅谈后端语言优缺点

    浅谈后端语言优缺点 兄弟连教育在前不久,回答了一个关于后端语言选型的问题,那么后端语言都有哪些,存在什么样的优缺点?因此兄弟连与大家分享一下心得. 语言优缺点 C/C++ C 语言虽然是非常贴近操作系 ...

  5. 【大话设计模式】——浅谈设计模式基础

    初学设计模式给我最大的感受是:人类真是伟大啊!单单是设计模式的基础课程就让我感受到了强烈的生活气息. 个人感觉<大话设计模式>这本书写的真好.让貌似非常晦涩难懂的设计模式变的生活化.趣味化 ...

  6. 乘法逆元 java_浅谈乘法逆元(示例代码)

    浅谈乘法逆元 乘法逆元,一般用于求解(frac{A}{C}(mod ~ P))的值,因为我们通过模的定义可以知道上式显然不等于(frac{A \% P}{B \% P}).例子有很多不再举了.那么如果 ...

  7. python列表和数组区别java_浅谈numpy中np.array()与np.asarray的区别以及.tolist

    array和asarray都可以将结构数据转化为ndarray,但是主要区别就是当数据源是ndarray时,array仍然会copy出一个副本,占用新的内存,但asarray不会. 1.输入为列表时 ...

  8. 指针java_浅谈Java与指针 - 穿梭于偶然

    尽管在java中没有显式的使用 假设People类已经定义,请大家考虑一下面这段代码: People p1 = new People("Csyor"); People p2 = p ...

  9. 中文文本校对源码java_浅谈中文文本自动纠错在影视剧搜索中应用与Java实现

    1.背景: 这周由于项目需要对搜索框中输入的错误影片名进行校正处理,以提升搜索命中率和用户体验,研究了一下中文文本自动纠错(专业点讲是校对,proofread),并初步实现了该功能,特此记录. 2.简 ...

  10. 编译原理代码生成器java_浅谈JVM编译原理-.java文件转变为.class文件的过程

    为什么需要编译? 我们平常写代码,有规范的命名方式,都能够看得懂,但是我们写的代码计算机是看不懂的,所以需要编译,也就是一个转换的过程,如下: 1.这个是咱们平时写的代码,就比较好理解,对人友好 2. ...

最新文章

  1. 【IBM Tivoli Identity Manager 学习文档】3 系统部署
  2. Windows 7系统如何设置锁定计算机快捷方式【技术小摘】
  3. 【数学与算法】KMeans聚类代码
  4. mysql高性能学习笔记03_MySQL高性能学习笔记
  5. SpringMVC教程--图片上传
  6. c++ map是有序还是无序的_C++ STL中Map的按Key排序和按Value排序
  7. 前馈神经网络——深度学习之神经网络核心原理与算法
  8. SpringBoot-iText-Pdf
  9. 24张最新可视化大屏模板,各行业数据直接套用
  10. Flink 滑动窗口优化
  11. VMWare安装报错:此安装程序要求您重新启动系统以完成 Microsoft VC Redistributable安装,然后重新运行该安装程序。
  12. android adb pull 文件夹,android – 我如何adb拉SD文件夹中的所有文件
  13. 罗马仕荣获中国质量认证中心、CESI颁发的全国首批“双新认证”证书
  14. 如何用python画出一般函数图_python如何画函数图像
  15. 变频技术在起重机上的应用
  16. linux三剑客有什么区别,学习Linux三剑客
  17. 长江大数据交易中心以数据安全标准护航安全和隐私
  18. Learning Pyramid-Context Encoder Network for High-Quality Image Inpainting论文理解
  19. kafka中leader和follower、AR、ISR、OSR、Controller的选举、为什么不能通过ZK的方式来选举partition的leader?
  20. 聊聊从逻辑门到操作系统的计算机

热门文章

  1. dispatch js实现_dva.js(and design)实现dispatch的回调函数
  2. P2184 贪婪大陆(线段树或树状数组+思维)
  3. 为什么总是封板又打开涨停_一旦持有个股出现涨停板,却封不住反复打开,意味着什么?...
  4. f5服务器维护,F5-LTM(服务器的负载均衡)网络结构和功能
  5. Apache 重写规则及参数详解,入门看这个就够了
  6. 网络就好似一个个树洞
  7. Office的许可证不是正版弹框解决
  8. 基础拍摄前期和基础后期修图
  9. 金山打字专业文章计算机,练打字试卷_推荐几篇适合学生练习打字的文章_淘题吧...
  10. 【转】宁做创业狼,不做打工狗(ZT)