观察者模式(又被称为发布-订阅模式、模型-视图模式、源-收听者模式或从属者模式)

观察者模式中,一个目标对象管理所有依赖于它的观察者对象,并且在它本身的状态改变时主动发出通知。

应用场景

拍卖会可以认为是观察者模式的一种,每个投标人都可以出价。拍卖师开始拍卖时,他观察是否有牌子举起出价。每次接受一个新的出价都改变了拍卖的当前价格,并且广播给所有的投标人。

在JDK中的应用

  • java.util.EventListener
  • javax.servlet.http.HttpSessionBindingListener
  • javax.servlet.http.HttpSessionAttributeListener
  • javax.faces.event.PhaseListener

参与角色

抽象主题(Subject):

抽象主题提供一个接口,可以增加和删除观察者对象;
Subject把所有观察者对象的引用保存到一个集合里,每个主题都可以有任何数量的观察者;

具体主题(ConcreteSubject):
存储有关状态,这些状态应与目标的状态保持一致;
将有关状态存入具体观察者对象;
在具体主题内部状态改变时,给所有登记过的观察者发出通知;
实现Observer的更新接口以使自身状态与目标的状态保持一致。

抽象观察者(Observer):
为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

具体观察者(ConcreteObserver):
实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

观察者模式的类图

观察者模式的意图是定义对象之间一对多的依赖关系,一个对象状态改变,其他相关联的对象就会得到通知并被自动更新。

观察者模式实例

在这个实例中,观察者能够注册此主题,任何在此主题上的内容提交导致的变化都会通知所有在注册的观察者。

Subject抽象主题:

public interface Subject {
//注册观察者
public void attach(Observer obs);
//移除观察者
public void detach(Observer obs); //通知观察者
public void noticeObservers();
//获得主题的更新信息
public String getUpdate(); }

  

Observer抽象订阅者:

public interface Observer {

	/**
* 获取主题变化,由Observer触发
*/
public void update(); /**设置主题对象*/
public void setSubject(Subject sbj);
}

  

ConcreteSubject具体主题:

public class ConcreteSubject implements Subject{

	private String message;//传递的消息体
private boolean changed;//消息状态标识
//存储注册的观察者集合
private List<Observer> observers; public ConcreteSubject(){
this.observers=new ArrayList<Observer>();
} /**
* 这里的Subject可以是主题订阅,具体关系中的老师-学生等
*/
@Override
public void attach(Observer obs) {
if(obs==null)
throw new NullPointerException("Null Observer");
if(!observers.contains(obs))
observers.add(obs);
} @Override
public void detach(Observer obs) {
observers.remove(obs);
} @Override
public void noticeObservers() {
List<Observer> temp=null;
/**
* 防止观察者收到订阅以前由被观察者发出的消息
*/
synchronized (ConcreteSubject.class) {
if(!changed)
return;
temp=new ArrayList<>(this.observers);
this.changed=false;
} for(Observer obs:temp){
/**调用观察者的方法*/
obs.update();
}
} @Override
public String getUpdate() {
return this.message;
} public void postMessage(String msg){
this.message=msg;
this.changed=true;
//通知到观察者
noticeObservers();
} }

  

ConcreteObserver具体观察者:

public class ConcreteObserver implements Observer{

	//此处用于标注不同的观察者
private String name;
//消息结果字段
private String result;
//设置主题
private Subject subject; public ConcreteObserver(String name){
this.name=name;
} @Override
public void update() {
/**从主题那里取得消息更新*/
result=subject.getUpdate();
/**处理消息*/
System.out.println(name+" get message "+result);
} //设置主题
@Override
public void setSubject(Subject sbj) {
this.subject=sbj;
} }

发布-订阅实例:

public class OBClient {

	public static void main(String[] args){
ConcreteSubject sbj=new ConcreteSubject(); ConcreteObserver obs1=new ConcreteObserver("obs1");
ConcreteObserver obs2=new ConcreteObserver("obs2");
ConcreteObserver obs3=new ConcreteObserver("obs3"); /**注册到主题*/
sbj.attach(obs1);
sbj.attach(obs2);
sbj.attach(obs3); /**设置被观察对象*/
obs1.setSubject(sbj);
obs2.setSubject(sbj);
obs3.setSubject(sbj); /**发送消息*/
sbj.postMessage("hello world!"); } }

测试结果:

参考:

JAVA中的观察者模式实例教程

观察者模式(Observer)解析例子

维基百科·观察者模式

行为型模式之Observer模式的更多相关文章

  1. Behavioral模式之Observer模式

    1.意图 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都得到通知并被自己主动更新. 2.别名 依赖(dependents).公布-订阅(Publish-Subscr ...

  2. Observer模式(观察者设计模式)

    Observer 设计模式? 在Observer模式中,当观察对象的状态发生变化时,会通知给观察者.Observer模式适用于根据对象状态进行相应处理的场景. Observer 并非主动观察,而是被动 ...

  3. 【行为型】Observer模式

    观察者模式意图解决一对多的依赖关系情形中,当被依赖对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新的问题.举个很简单的例子说,假如一个游戏中的角色的某个属性状态发生了变化,此处不妨假设为 ...

  4. 004-行为型-03-观察者模式(Observer)

    一.概述 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern).比如,当一个对象被修改时,则会自动通知它的依赖对象. 定义了对象之间的一对多依赖,让多个观察者对象同时监听某一 ...

  5. Java 实现观察者(Observer)模式

    1. Java自带的实现 类图 /** * 观察目标 继承自 java.util.Observable * @author stone * */ public class UpdateObservab ...

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

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

  7. Java观察者模式(Observer模式)

    Java深入到一定程度,就不可避免的碰到设计模式(design pattern)这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循 ...

  8. 建造者模式与原型模式/builder模式与prototype模式/创建型模式

    建造者模式 定义 用于简化复杂对象的创建 JDK中的建造者模式 java.lang.StringBuilder中的append()方法,每次调用后返回修改后的对象本身. public StringBu ...

  9. Observer 模式

    Observer模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系,并且做到当“一”变化的时候,依赖这个“一”的多也能够同步改变.最常见的一个例子就是:对同一组数据进行 ...

随机推荐

  1. c#.net单例模式的学习记录!

    一. 单例(Singleton)模式 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类必须给所有其它对象提供这一实例. 单例模式应用: 每台计算机可以有若干个打印机 ...

  2. redis 操作 list 的测试

    lpush 从头部压入数据 127.0.0.1:6379> lpush listname value1 (integer) 1//返回list的当前长度 127.0.0.1:6379> l ...

  3. ASP.NET MVC4 URL传递汉字参数不能正确接收

    前两天写了个项目,在chrome上做的开发和测试. 拿给了产品,产品使用IE8.7.6进行测试的时候,发现很多报错.原因是URL里面的汉字在后台接收时显示的时乱码. 百度之~~ 最终解决方案, 在WE ...

  4. sqlserver 数据库索引建立原则

    1.始终包含聚集索引 当表中不包含聚集索引时,表中的数据是无序的,这会降低数据检索效率.即使通过索引缩小了数据检索的范围,但由于数据本身是无序的,当从表中提取实际数据时,会产生频繁的定位问题,这也使得 ...

  5. Win10 磁盘占用 100% 有效解决办法

    立即查看 任务管理器,看看是不是有一个 服务主机 unistack服务组或者找类似名称的,点开以后你会看到里面有同步主机 blablah请你毫不犹豫的结束它!结束它!结束它! 按下WIN+R调出运行, ...

  6. Download Excel file with Angular

    源码连接(编写中) 用Angular下载后台返回的Excel文件,用Blob实现,引用FileSaver.js 后台C#代码: [WebMethod] public static byte[] Cal ...

  7. orpsocv2 从ROM(bootrom)启动分析--以atlys板子的启动为例子

    1 复位后的启动地址 1) 复位后,启动地址在or1200_defines.v最后宏定义,atlys板子的目录:orpsocv2\boards\xilinx\atlys\rtl\verilog\inc ...

  8. php数组操作集锦- 掌握了数组操作, 也就掌握了php

    参考下面的文章, 是很好的: http://www.cnblogs.com/staven/p/5142515.html http://pcwanli.blog.163.com/blog/static/ ...

  9. Java 中文乱码问题总结

    开发java应用出现乱码是很常见的,毕竟现在unicode的使用还不是很广泛,在使用gb2312(包含了gbk简体,big5繁体)的系统中要正确 实现中文的display和数据库的存储是最基本的要求. ...

  10. ES5新语法forEach和map及封装原理

    ### forEach 在es5中提供了forEach方法进行遍历,其实就是模仿了jQuery中each方法,不过将 i 于v进行了调换,下面两种方法进行对比一下 var arr = [ 11, 22 ...