定义

  观察者模式属于对象行为型模式。

  在对象之间定义一对多的依赖,这样一来当一个对象改变状态,依赖它的对象都会收到通知并自动更新。

优点

  1、  主题和观察者之间抽象耦合。无论什么对象主要实现了特定的接口(如本文中的Observable),就可以成为观察者对象。

  2、  支持广播通信。就像一个播音员不需要知道谁在收听她的播音,只负责播音,而听不听就是听众的事了。这相当于给了你在任何时候都可以增加或者删除观察者的自由。

适用范围

  当对象之间是一种一对多的关系时。好比有一份文件要同时分发给多个人。

模式结构

各个角色的作用:

  Subject(主题):目标知道它的观察者。可以有任意多个观察者观察同一个目标;提供注册和删除观察者对象的接口。

  Observer(观察者):为那些在目标发生改变时需获得通知的对象定义一个更新接口。

  ConcreteSubject(具体的主题):当它的状态发生改变时,向它的各个观察者发出通知。

  ConcreteObserver(具体观察者):实现Oberserver的更新接口以使自身状态与目标状态一致。

UML图

    

两种方式:

  1、(推)主题对象主动推送;

  2、(拉)主题对象通知观察者,观察者自己去获取需要的信息;

  这两种方式会在下面介绍。

例子

  写一个简单的程序来说明问题:假如现在有一个广播站在播音,有许多收音机在收听。

  面向接口编程能够利用多态,从而降低对象之间的耦合度。

 package com.tony.observer;

 /**
* 具体的主题类必须实现这个接口
*
*/
public interface Subject { //注册观察者
public void register(Observable observer);
//移除观察者
public void remove(Observable observer);
//推送消息
public void update(String message); }
 package com.tony.observer;

 import java.util.ArrayList;
import java.util.List; /**
* 相当于ConcreteSubject,具体的主题类
*
*/
public class Radiostation implements Subject{ private List<Observable> observers; public Radiostation(){
observers = new ArrayList<Observable>();
} public void register(Observable observer){
observers.add(observer);
System.out.println("have "+observers.size()+" observer are listening...");
} public void remove(Observable observer){
observers.remove(observer);
System.out.println("a observer has gone...left "+observers.size()+" observer");
} public void update(String message){
for(Observable observer:observers){
observer.update(message);
}
}
}
 package com.tony.observer;

 /**
* 相当于Observer,所有的观察者必须实现这个接口
*
*/ public interface Observable { //更新数据
public void update(String message);
//成为主题对象的观察者,开始监听
public void register();
//不再监听主题对象
public void remove(); }
 package com.tony.observer;

 /**
* 相当于ConcreteObserver,观察者对象
*
*/
public class Radio implements Observable { private Subject subject; public Radio(Subject subject){
this.subject = subject;
} @Override
public void update(String message) {
display(message);
} @Override
public void register() {
subject.register(this);
} @Override
public void remove() {
subject.remove(this);
} public void display(String message){
System.out.println("get message from radiostation:"+message);
} }
 package com.tony.observer;
/**
* 测试观察者模式
*
*/
public class Test {
public static void main(String[] args) { Subject radiostation = new Radiostation(); Radio o1 = new Radio(radiostation);
Radio o2 = new Radio(radiostation); //注册
o1.register();
o2.register(); //更新消息
radiostation.update("hello world");
radiostation.update("over"); //退出监听
o1.remove();
o2.remove();
}
}

运行结果:

  这种实现方法属于“推”:主题主动将数据推送给观察者。其实还有另外一种叫做“拉”的方式:主题不主动将数据推送给观察者,只是给它们一个更新提示,接收的权利在观察者手上!

  与“拉”相比较,“推”有个很大的缺点:当推送的数据量很大的时候,会对程序运行性能产生影响!就像安卓手机某些后台应用:不经过你的同意自动将服务器中的一些数据下载的你的手机上。而“拉”这种方式就没有这样的情况,就好像你关注的公众号一样:给你推送消息时并没有把所有内容都推送过来,只是把一个标题发给你,想不想看在于你。

  但是”推“这种方式比较符合设计模式的原则,所以一般使用的都是这种方式。

总结

  观察者模式应用很广,不仅在你写代码的时候用到,你在生活当中也时常能够遇到:比如走在校园里收听到的广播:广播站是主题,你就是观察者。当你进入到能够听见广播的范围时,你就成了一个观察者:播音主持说的话就是要更新的数据,通过广播站这个主题将数据发送给你们,你们负责收听。

  必须能够熟练使用。

  其他模式:设计模式专栏

参考文献

  《Head First 设计模式》

  《设计模式》

Java设计模式 - 观察者模式的更多相关文章

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

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  2. 【设计模式】Java设计模式 - 观察者模式

    [设计模式]Java设计模式 - 观察者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 @一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...

  3. JAVA 设计模式 观察者模式

    用途 观察者模式 (Observer) 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象. 这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观 ...

  4. Java设计模式--观察者模式到监听器

    观察者模式是对象的行为模式.又叫做发布-订阅模式.模型-视图模式.源-监听器模式. 抽象主题角色:主题角色将所有对观察者对象的引用到保存在一个集合里,每个主题都可以拥有任意数量的观察者.抽象主题提供一 ...

  5. Java设计模式の观察者模式(推拉模型)

    目录: 一.观察者定义 二.观察者模式的结构(推模式实现) 三.推模型和拉模型(拉模式实现) 四.JAVA提供的对观察者模式的支持 五.使用JAVA对观察者模式的支持(自带推模式实现实例) 一.观察者 ...

  6. 我的Java设计模式-观察者模式

    相信大家都有看过<喜洋洋与灰太狼>,说的是灰太狼和羊族的"斗争",而每次的结果都是灰太狼一飞冲天,伴随着一句"我还会回来的......".为灰太狼感 ...

  7. java设计模式-观察者模式学习

    最近学习了设计模式中的观察者模式,在这里记录下学习成果. 观察者模式,个人理解:就是一个一对多模型,一个主体做了事情,其余多个主体都可以观察到.只不过这个主体可以决定谁去观察他,以及做什么事情可以给别 ...

  8. Java设计模式——观察者模式(事件监听)

    最近在看Tomcat和Spring的源码,在启动的时候注册了各种Listener,事件触发的时候就执行,这里就用到了设计模式中的观察者模式. 引-GUI中的事件监听 想想以前在学Java的GUI编程的 ...

  9. JAVA设计模式—观察者模式和Reactor反应堆模式

    被观察者(主题)接口 定义主题对象接口 /**抽象主题角色: 这个主题对象在状态上发生变化时,会通知所有观察者对象 也叫事件对象 */ public interface Subject { //增加一 ...

随机推荐

  1. Java并发编程:并发容器之ConcurrentHashMap(转载)

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...

  2. 点我吧工作总结(技术篇) zookeeper

    我思故我在,提问启迪思考! 1.什么是zookeeper? 2.zookeeper与dubbo.springMVC之间的协同工作? http://doc.okbase.net/congcong68/a ...

  3. 解决 WinXP下 libcurl.dll 无法定位程序输入点GetTickCount64问题

    1. 问题描述 用 IDA 打开libcurl.dll 可以在导入表看到对 GetTickCount64的引用,在 xp 的kernel32.dll中没有 GetTickCount64, 所以会出现  ...

  4. 代码设置Shape和Selector

    开发中经常需要使用Shape和Selector,如果每个都用xml设置的话,会占用apk大小,同时命名多了也会混乱,使用代码来设置会方便很多. 需要用到2个类:GradientDrawable和Sta ...

  5. 事件委托 documentFragment

    如果有一个列表页,页面结构是外面一个BODY, 里面有一万个子DIV,每个DIV里面有一些文字,这些文字都不相同.需求是,点击一个DIV,要求弹个alert框,将DIV里的文字显示出来.你会怎么做. ...

  6. javaweb学习总结(十一)——使用Cookie进行会话管理

    一.会话的概念 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾 ...

  7. 【转】给Windows + Apache 2.2 + PHP 5.3 安装PHP性能测试工具 xhprof

    原文链接:http://blog.snsgou.com/post-816.html 1.下载XHProf 到这里 http://dev.freshsite.pl/php-extensions/xhpr ...

  8. (原) 1.1 Zookeeper单机安装

    本文为原创文章,转载请注明出处,谢谢 zookeeper 单机安装配置 1.安装前准备 linux系统(此文环境为Centos6.5) Zookeeper安装包,官网https://zookeeper ...

  9. i++,++i,Math.max,hasOwnPrototype.ajax,indexOf(),firefox的一些东西,jquery的contains函数,window.open

    一.i++与++i的区别 1 var i=0;3 console.log(i++)5 0 1 var j=0; 2 3 console.log(++j) 4 1 a=++i;相当于i=i+1;a=i; ...

  10. 高性能javascript学习笔记系列(1) -js的加载和执行

    这篇笔记的内容主要涉及js的脚本位置,如何加载js脚本和脚本文件执行的问题,按照自己的理解结合高性能JavaScript整理出来的 javascript是解释性代码,解释性代码需要经历转化成计算机指令 ...