观察者模式在软件编程中用的较多,我不善于表达我就用在网上看到的故事,和生活的例子说下基本思想

故事:

小雪是一个非常漂亮的女孩,漂亮的女孩总是有很多的追求者,而且追求者的队伍在不断的变动,随时有人进入这个队伍,也有人退出。男孩们追求女孩时总是表现出120%的关心,当小雪私自游玩时总是不断收到追求者询问小雪位置变动的消息,小雪也不胜其烦,但小雪是如此的一个善良的女孩,她总是打断自己正常的生活回复男孩们的消息。而男孩们由于要不断的关心小雪的位置变化也弄的精疲力竭,而且还影响正常的工作。在这样一个简单的故事场景中我们发现了什么?来看看小雪和男孩们的烦恼: 
  1.男孩们必须不断的询问小雪的位置变化,从而打断正常的工作; 
  2.小雪也要不断的接受男孩们的询问,有的时候小雪的位置并没有发生变化,还是要不断的回复男孩们的询问,也影响正常的工作。

3.如果给各个男孩们回复问题的方式都不尽相同,小雪还要知道不同的回复方式,而且不断的有新的男孩们增加进来,还不知道未来有什么新的回复方式。

看到这么多烦恼,我们创意无限的Nokia公司给小雪和男孩们提出了解决方案: 
    Nokia公司荣誉出品了一款带有GPRS功能的手机,该手机保存着一个订阅位置变化短信通知的电话列表,当该手机检测到位置发生变化就会向这个订阅列表里的所有手机发送短信。看到Nokia这个解决方案,男孩们和小雪都应该松一口气,他们各自都可以按照自己正常的生活习惯,只有状态发生变化时候各自才会进行通信。

观察者模式还可以用生活中一个例子来表达,就是从邮局订杂志。假如有一个叫 妮妮 的女孩在A邮局订了《时尚女孩》的杂志,又在B邮局订了《知音》杂志,并且告诉这两家邮局,如果杂志到了就给我打电话我自己来拿,然后邮局就在系统中注册下这个女孩姓名,电话等信息。妮妮剩下的就是等邮局的电话来取杂志了。如果杂志到了,邮局打电话给妮妮说,您的杂志到了,请到某某邮局来取(这相当于程序中把对象的引用——邮局名,传给观察者),如果只说您的杂志到了,请到邮局来取,妮妮怎么知道去哪个邮局拿杂志呀。

下面的程序模仿上面的情形,一个随机数产生对象和两个观察者,这两个观察者都在随机数产生对象那里注册了,意思说如果你产生了新的数字,就通知我一声。

结构图:

类说明

 名称  功能说明
 Observer  表示观察者的接口,要成为观察者必须实现此接口才行
 NumberGenerator  表示产生数值的抽象类
 RandomNumberGenerator  产生随机数的类,继承于NumberGenerator
 NumberObserver  数字观察者,会打印出变化的数字
 SymbolObserver  符号观察者,打印N 个符号,打印多少个符号,由接受到的数值确定

1.Observer

Java代码  
  1. package com.pattern.observer;
  2. public interface Observer {
  3. public abstract void update(NumberGenerator generator);
  4. }

2.NumberGenerator

Java代码  
  1. package com.pattern.observer;
  2. import java.util.ArrayList;
  3. import java.util.Iterator;
  4. /**
  5. * @project JavaPattern
  6. * @author sunnylocus
  7. * @verson 1.0.0
  8. * @date   Aug 27, 2008 1:35:34 PM
  9. * @description 产生数值的抽象类
  10. */
  11. public abstract class NumberGenerator {
  12. private ArrayList observers = new ArrayList();  //存储Observer
  13. /** 添加观察者*/
  14. public void addObserver(Observer observer) {
  15. observers.add(observer);
  16. }
  17. /** 删除观察者*/
  18. public void delObserver(Observer observer) {
  19. observers.remove(observer);
  20. }
  21. /** 通知所有观察者*/
  22. public void notifyObservers() {
  23. Iterator it = observers.iterator();
  24. while(it.hasNext()) {
  25. Observer o =(Observer) it.next();
  26. o.update(this);//this相当于上面提到的邮局名
  27. }
  28. }
  29. public abstract int getNumber();//获取数字
  30. public abstract void generate();//产生数字
  31. }

3.RandomNumberGenerator

Java代码  
  1. package com.pattern.observer;
  2. import java.util.Random;
  3. /**
  4. * @project JavaPattern
  5. * @author sunnylocus
  6. * @verson 1.0.0
  7. * @date   Aug 27, 2008 1:48:03 PM
  8. * @description 用于产生随机数及通知观察者的类
  9. */
  10. public class RandomNumberGenerator extends NumberGenerator{
  11. private Random random = new Random();//随机数产生器
  12. private int number;   //用于存放数字
  13. public void generate() {
  14. for(int i=0 ; i < 5; i++) {
  15. number = random.nextInt(10);//产生10以内的随机数
  16. notifyObservers();  //有新产生的数字,通知所有注册的观察者
  17. }
  18. }
  19. /** 获得数字*/
  20. public int getNumber() {
  21. return number;
  22. }
  23. }

4.NumberObserver

Java代码  
  1. package com.pattern.observer;
  2. /** 以数字表示观察者的类*/
  3. public class NumberObserver implements Observer{
  4. public void update(NumberGenerator generator) {
  5. System.out.println("NumberObserver:"+ generator.getNumber());
  6. try {
  7. Thread.sleep(1000 * 3); //为了能清楚的看到输出,休眠3秒钟。
  8. }catch(InterruptedException e) {
  9. e.printStackTrace();
  10. }
  11. }
  12. }

5.SymbolObserver

Java代码  
  1. package com.pattern.observer;
  2. /** 以符号表示观察者的类*/
  3. public class SymbolObserver implements Observer{
  4. public void update(NumberGenerator generator) {
  5. System.out.print("SymbolObserver:");
  6. int count = generator.getNumber();
  7. for(int i = 0 ; i < count; i ++) {
  8. System.out.print("*^_^*  ");
  9. }
  10. System.out.println("");
  11. try {
  12. Thread.sleep(1000 * 3);
  13. }catch(InterruptedException e){
  14. e.printStackTrace();
  15. }
  16. }
  17. }

6.Main(测试类)

Java代码  
  1. package com.pattern.observer;
  2. public class Main {
  3. public static void main(String[] args) {
  4. //实例化数字产生对象
  5. NumberGenerator generator = new RandomNumberGenerator();
  6. //实例化观察者
  7. Observer observer1 = new NumberObserver();
  8. Observer observer2 = new SymbolObserver();
  9. //注册观察者
  10. generator.addObserver(observer1);
  11. generator.addObserver(observer2);
  12. generator.generate(); //产生数字
  13. }
  14. }

7.结果输出

设计思想:

观察者模式定义了对象之间的一对多的依赖关系,当一个对象的状态发生改变时,所有它的依赖对象将被自动通知并更新

转自:http://sunnylocus.iteye.com/blog/233212

===============================华丽的分割线===================================================================

Observer模式的意图是“定义对象间的一种一对多的依赖关系(NumberGenerator和Observer就是一对多的关系),当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”。从这段话里我们可以得到两个信息,如下: 
1, 观察者Observer(具体执行操作的对象,有多个,在上面的例子里就是Observer以及实现其的NumberObserver和SymbolObserver) 
2, 被观察者Observable(顾名思义是被观察的对象,如果该对象发生某些变化则通知观察者执行对应的操作,在上面的例子里就是NumberGenerator和RandomNumberGenerator)

总结来说,所有观察者Observer都会实现一个共同的接口,这个接口中会定义一个方法,以供需要通知观察者时调用;观察者模式中被观察者Observable中会持有若干个Observer对象,一般是放在一个集合中,并且提供添加Observer、删除Observer和遍历Observer集合挨个调用Observer接口方法来通知各个Observer的方法;在使用的时候,初始化Observable时就会添加进各个需要通知的Observer,在调用完Observable主要业务后,调用遍历Observer的方法来通知各个Observer。

注:

在java.util包中已经提供了观察者模式的java类,包括接口Observer(包含update方法,在通知时调用)、类Observable(包含了添加、删除、通知Observer等方法)

Observer模式相关推荐

  1. 移动项目开发笔记(.Net下的观察者(Observer)模式)

    下面是一些关于这个Observer的基本一些概念,在很多地方都能看到,这里我归纳这这里便于以后查阅: 一.发布订阅模型(pub-sub) 二.动机(Motivation) 在软件构建过程中,我们需要为 ...

  2. C# 关于委托和事件的妙文:通过一个例子详细介绍委托和事件的作用;Observer模式简介...

    委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见 ...

  3. java获取jsp 组件,利用Observer模式解决组件间通信问题-JSP教程,Java技巧及代码

    1. 问题的提出 以前做一个界面的时候常常会遇到这样的尴尬情况:希望保留各个独立的组件(类),但又希望它们之间能够相互通信.譬如windows中的explorer,我们希望鼠标点击左边是树型目录的一个 ...

  4. 设计模式-Observer模式

    目录 角色组成 抽象主题(Subject) 具体主题(Concrete Subject) 抽象观察者(Observer) 具体观察者(Concrete Observer) 具体实现 总结 观察者模式( ...

  5. Observer 模式在eHR中的应用

    接触模式应该是在大三的时候,那时候感觉是模式让我真正的认识到了OO,现在毕业了,也工作有半年了,终于体会到了"商业特色的软件开发"了,根本就没有多余的时间去考虑运用什么模式.怎样使 ...

  6. Observer模式在J2EE中的实现

    引言: 设计模式是经验的文档化.它是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述.更通俗的来说,它是一个问题/解决方案对.一旦我们掌握了设计模式,就等于拥有了一支强有力的专家队伍.它 ...

  7. 设计模式--观察者(Observer)模式

    模式定义 定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖者都会收到通知并更新 类图 应用场景 当更改一个对象的状态可能需要更改其他对象,并且实际 ...

  8. 重温Observer模式--热水器·改(转载)

    引言 在 C#中的委托和事件 一文的后半部分,我向大家讲述了Observer(观察者)模式,并使用委托和事件实现了这个模式.实际上,不使用委托和事件,一样可以实现Observer模式.在本文中,我将使 ...

  9. java observer模式_Java观察者模式(Observer)详解及应用

    Java观察者模式(Observer)详解及应用 (2011-12-15 14:03:30) 标签: 杂谈 Java观察者模式(Observer)详解及应用 由于网站带有弱sns功能,因此需要设计关注 ...

  10. 设计模式学习笔记——观察者(Observer)模式

    设计模式学习笔记--观察者(Observer)模式 @(设计模式)[设计模式, 观察者模式, Observer] 设计模式学习笔记观察者Observer模式 基本介绍 观察者案例 类图 实现代码 Ob ...

最新文章

  1. jsp页面中静态文件的时间戳
  2. 计算机一级考模拟试题,计算机一级MSOffice考前模拟试题「附答案」
  3. php函数多个参数_php中,用函数,如果有很多个参数,只使用最后一个参数,有什么优雅的写法?...
  4. 如何在Chatbot中应用深度学习
  5. HTML页面把list转成array,c# – 将Collection转换为Array或List的快速方法?
  6. leaflet自定标签json_Windows Terminal更新后,自定义配置失效?快捷键无法使用?
  7. 结对编程其实可以变变?
  8. Leap 使用注意事项
  9. react 表单设计器_神器:让你相见恨晚的5个React应用程序库
  10. VBA InStr 函数
  11. php和vue实现智商在线测试题
  12. jQuery超酷轻量级响应式lightbox插件
  13. 5W2H在IC设计中的应用
  14. 2020年下半年系统架构设计师下午真题及答案解析
  15. 系统安装教程之硬盘分区格式化(MBR或GPT)
  16. 飞行棋程序(附源码)
  17. 使用magick 遇到 convert: Non-conforming drawing primitive definition `text'错误的解决办法...
  18. Windows10 中的字母映射表
  19. jsdelivr cdn npm替代方案
  20. 【flutter】使用permission_handler配置android和 iOS的权限

热门文章

  1. 职场:职业摧毁工作热情的场所
  2. 多商户商城系统功能拆解35讲-平台端营销-拼团商品
  3. iPhone技巧之「合并PDF文档」
  4. C语言二维数组中:主次对角线求和,上下三角求和,杨辉三角,矩阵转置
  5. 关于星云图获取最大面积的C++案例的DEMO
  6. 入门力扣自学笔记52 C++ (题目编号929)
  7. 凌波微步Flink——Flink的技术逻辑与编程步骤剖析
  8. 欧洲要加强反垄断法打击美国科技公司
  9. atm系统的用例模型_UML建模语言7种图(以银行ATM系统为例)
  10. vscode react插件