一、观察者模式概述

  观察者模式主要用于 1 :N 的通知。当一个对象(目标对象 Subject 或 Observable)的状态变化时,它需要通知一系列对象(观察者对象 Observer),令它们做出响应。

  通知观察者的方式:

    (1)推

        每次都会把通知以广播的方式发送给所有观察者,所有观察者只能被动接收。

    (2)拉

        观察者只要知道有情况即可。至于什么时候获取内容,获取哪些内容,都可以自主决定。

二、观察者模式示例代码

 /**
* 观察者对象接口
* @author CL
*
*/
public interface Observer {
/**
* 更新主题
* @param subject
*/
void update(Subject subject); }
 /**
* 主题对象(目标对象)
* @author CL
*
*/
public class Subject { protected List<Observer> list; public Subject() {
list = new ArrayList<Observer>();
} public void addObserver(Observer observer) {
list.add(observer);
} public void removeObserver(Observer observer) {
list.remove(observer);
} /**
* 通知所以观察者更新状态
*/
public void notifyAllObserver() {
for (Observer o : list) {
o.update(this);
}
} }
 /**
* 具体的目标对象
* @author CL
*
*/
public class ConcreteSubject extends Subject { /**
* 状态
*/
private int state; public int getState() {
return state;
} public void setState(int state) {
this.state = state;
//若主题对象(目标对象)发生的状态发生改变,请通知所有观察者更新状态
this.notifyAllObserver();
} }
 /**
* 观察者
* @author CL
*
*/
public class ObserverA implements Observer { private int myState; //myState需要和目标对象的state保持一致 @Override
public void update(Subject subject) {
myState = ((ConcreteSubject) subject).getState();
} public int getMyState() {
return myState;
} public void setMyState(int myState) {
this.myState = myState;
} }

  测试:

 /**
* 测试观察者模式
* @author CL
*
*/
public class Client { public static void main(String[] args) {
//目标对象
ConcreteSubject sub = new ConcreteSubject(); //创建三个观察者
ObserverA o1 = new ObserverA();
ObserverA o2 = new ObserverA();
ObserverA o3 = new ObserverA(); //将这三个观察者添加到目标对象subject的容器中
sub.addObserver(o1);
sub.addObserver(o2);
sub.addObserver(o3); //修改目标对象的状态值
sub.setState(100); System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState()); System.out.println("----------------------"); //修改目标对象的状态值
sub.setState(10); System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState());
}
}

  控制台输出:

100
100
100
----------------------
10
10
10

三、JDK 中提供类和方法实现观察者模式

  

 import java.util.Observable;

 /**
* 目标对象
* @author CL
*
*/
public class ConcreteSubject extends Observable {
private int state; public int getState() {
return state;
} public void setState(int state) {
this.state = state; setChanged(); //表示目标对象已经更改状态 notifyObservers(); //通知所有观察者
} }
 import java.util.Observable;
import java.util.Observer; /**
* 观察者对象
* @author CL
*
*/
public class ObserverA implements Observer { private int myState; @Override
public void update(Observable o, Object arg) {
myState = ((ConcreteSubject) o).getState();
} public int getMyState() {
return myState;
} public void setMyState(int myState) {
this.myState = myState;
} }

  测试:

 /**
* 测试利用java.util.*包中的类Observable和接口Obsever实现的观察者模式
* @author CL
*
*/
public class Client { public static void main(String[] args) {
//目标对象
ConcreteSubject sub = new ConcreteSubject(); //创建三个观察者
ObserverA o1 = new ObserverA();
ObserverA o2 = new ObserverA();
ObserverA o3 = new ObserverA(); //将这三个观察者添加到目标对象subject的容器中
sub.addObserver(o1);
sub.addObserver(o2);
sub.addObserver(o3); //修改目标对象的状态值
sub.setState(666); System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState()); System.out.println("----------------------"); //修改目标对象的状态值
sub.setState(123); System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState());
}
}

  控制台输出:

666
666
666
----------------------
123
123
123

四、观察者模式常见开发应用场景

  (1)手机APP中每天的推送广告;

  (2)多人联机网络游戏中,服务器实时分发所有玩家的状态;

  (3)Servlet 中监听器的实现;

  (4)Android 中广播机制;

  (5)JDK 的 AWT 事件处理模型,基于观察者模式的委派事件模型(Delegation Event Model)

      事件源:目标对象

      事件监听器:观察者

  (6)…………

GOF23设计模式之观察者模式(observer)的更多相关文章

  1. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  2. 8.5 GOF设计模式四: 观察者模式Observer

    GOF设计模式四: 观察者模式Observer  现实中遇到的问题  当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式  观察者模式 ...

  3. 【GOF23设计模式】观察者模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_观察者模式.广播机制.消息订阅.网络游戏对战原理 package com.test.observer; import ja ...

  4. 人人都会设计模式:观察者模式--Observer

    https://segmentfault.com/a/1190000012295887 观察者模式是抽像通知者和观察者,达到具体通知者跟具体观察者没有偶合.能达到不管是切换通知者,或者是切换观察者,都 ...

  5. 二十四种设计模式:观察者模式(Observer Pattern)

    观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...

  6. [设计模式] 19 观察者模式 Observer Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对观察者模式是这样说的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.当一个 ...

  7. c#设计模式之观察者模式(Observer Pattern)

    场景出发 一个月高风黑的晚上,突然传来了尖锐的猫叫,宁静被彻底打破,狗开始吠了,大人醒了,婴儿哭了,小偷跑了 这个过程,如果用面向对象语言来描述,简单莫过于下: public class Cat { ...

  8. JAVA设计模式之观察者模式 - Observer

    有趣的事情发生时,可千万别错过了!有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事.对象甚至在运行时可决定是否要继续被通知.有了观察者,你将会消息灵通. 介绍 观察者模式的定义: 在对象之间 ...

  9. 设计模式之观察者模式(Observer pattern)

    最近参加了一次面试,其中笔试题有一道编程题,在更换掉试题的描述场景后,大意如下: 上课铃声响起,学生A/B/C/D进入教室:下课铃声响起,学生A/B/C/D离开教室. 要求使用设计模式的思想完成铃与学 ...

随机推荐

  1. CMDB配置资源管理数据库(理解)

    CMDB是运维自动化的基础,它为日志系统,发布系统,监控系统等运维系统(ELK,zabbix,open-falcon)提供接口函数, 第一种方式:Agent方法实现,agent不能直接访问数据库,因为 ...

  2. Alt+Shift+R组合键,用来在一个java文件中批量的重命名变量。

    myeclipse和eclipse集成编译软件,都提供了一个快捷键用来批量重命名变量:Alt+Shift+R组合键,用来在一个java文件中批量的重命名变量.扩展知识:如果想要重命名文件名,又不想手动 ...

  3. PHP use

    PHP 7 use 语句  PHP 7 新特性 PHP 7 可以使用一个 use 从同一个 namespace 中导入类.函数和常量: 实例 实例 // PHP 7 之前版本需要使用多次 use us ...

  4. [Scala]Scala学习笔记四 类

    1. 简单类与无参方法 class Person { var age = 0 // 必须初始化字段 def getAge() = age // 方法默认为公有的 } 备注 在Scala中,类并不声明为 ...

  5. liunx工具学习之taskset

    当你优化多线程任务的时候,发现某个线程在不同的核上跳转较大,从而耗费CPU的时候想法肯定是想可以把对应线程绑定到特定的核上,可是每次这样操作每次尝试看效果的时候都要重启进程,那有没有一个工具可以直接处 ...

  6. 2013-05-25 14:04 zend studio10正式版如何汉化?

    选择Help菜单->Install New Software...在Work with框中复制此地 址:http://download.eclipse.org/technology/babel/ ...

  7. Linux 查看版本號

    前言 剛剛升級了Fedora27,想要一查究竟.無奈竟不知如何查看linux版本,依稀記得uname好像可以,輸入之後就尷尬了. $ uname Linux 查看網上各種教程,看到一個不錯的博文,爲[ ...

  8. 【剑指offer】输入一颗二叉树的根节点,判断是不是平衡二叉树,C++实现

    原创博文,转载请注明出处! # 题目 # 举例 # 思路 由平衡二叉树的定义可知,判断二叉树是否是平衡二叉树的关键在于判断任意结点是否是平衡结点.后序遍历二叉树,判断节点的子树是否平衡并计算节点的子树 ...

  9. 前端ajax异步传值以及后端接收参数的几种方式

    原文参考 异步传值 前台往后台传值呢,有很多种方式,大家听我细细道来. 第一种呢,也是最简单的一种,通过get提交方式,将参数在链接中以问号的形式进行传递. // 前台传值方法 // 触发该方法调用a ...

  10. redis整合异常总结

    问题:org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field ' ...