"围观"设计模式(19)--行为型之观察者模式(Observer Pattern)

观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。----WIKIPEDIA


个人理解

观察者模式,就是使得被观察者中持有观察者的对象实例,在发生某些事件的时候,通过notify“通知”观察者,完成相应的操作,他也叫作发布-订阅模式,定义对象间一对多的依赖关系,使得被观察者对象产生动作,即可通知其依赖的对象该被观察者发生了变更。


案例解析

正好前几天买了两只巴西龟,以这个为例子,乌龟也时会饿的,他饿了我就要去喂它吃的,这样的话,可以说正好用的到观察者模式。

推的方式

public interface Observable {

	// 添加观察者
	public void addObserver(Observer observer);
	// 删除观察者
	public void removeObserver(Observer observer);
	// 通知观察者
	public void notifyObservers(String info);
}

public interface Observer {

	// 喂食
	public void feed(String info);
}

public class Turtle implements Observable{

	private List<Observer> observerList = new ArrayList<Observer>();
	
	public void hungry(){
		this.notifyObservers("我饿了!");
	}

	@Override
	public void addObserver(Observer observer) {
		observerList.add(observer);
	}

	@Override
	public void removeObserver(Observer observer) {
		if(observerList != null && observerList.contains(observer)){
			observerList.remove(observer);
		}
	}
	
	@Override
	public void notifyObservers(String info) {
		for (Observer observer : observerList) {
			observer.feed(info);
		}
	}
}

public class XX implements Observer {

	@Override
	public void feed(String info) {
		System.out.println("喂饲料!");
	}
	
}

这里的情况是Turtle类明确知道它要通知观察者什么,那么这种方式可以看成是推的方式,但是并不一定都是一定知道对方想要什么,那么这个时候,需要一种拉取得方式,也就是将自身的实例传递给观察者,交由观察者自己去决定获取什么也就是拉取什么。


拉的方式

主要的变更如下:

public class Turtle2 implements Observable2 {

	private List<Observer2> observerList = new ArrayList<Observer2>();
	
	public void hungry(){
		this.notifyObservers();
	}

	@Override
	public void addObserver(Observer2 observer) {
		observerList.add(observer);
	}

	@Override
	public void removeObserver(Observer2 observer) {
		if(observerList != null && observerList.contains(observer)){
			observerList.remove(observer);
		}
	}
	
	@Override
	public void notifyObservers() {
		for (Observer2 observer : observerList) {
			observer.feed(this);
		}
	}

	@Override
	public boolean isNeedFeed() {
		return true;
	}
}

观察者模式的优点

1. 观察者与被观察者之间是抽象耦合:扩展被观察者和观察者时较容易。

2. 建立一套触发机制,经过一系列的触发机制,形成触发链。


观察者模式的缺点

多级触发的时候,效率让人担忧,在设计的时候要充分的考虑这一点。


观察者模式的适用范围

1. 关联行为场景。

2. 事件的多级触发。

3. 跨系统的消息交换场景,消息队列的处理机制。


源代码下载

设计模式源代码下载地址


推荐阅读

"围观"设计模式(18)--行为型之模板方法模式(TemplateMethod Pattern) 

"围观"设计模式(16)--结构型之组合模式(Composite Pattern)


本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。

Kafka入门(一) - 2016-06-09 14:06:00

一,消息队列的分类     1,点对点               消息生产者生产消息发送到 queue 中,然后消息消费者从 queue 中取出并且消费消息。                               注意: 1 ,消息被消费以后, queue中不再有存储,所以消息消费者不可能消费到已经被消费的消息。            2 ,Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。       2,发布订阅                  消息生产者(发布)将
一、序言 系列博客文章都是研读Gof的Design Patterns这本书的总结分享,书上的有些例子代码不是很全,这边依葫芦画瓢还原了一些代码,可供运行。目前,网络上很多分享设计模式内容的博客文章,都很经典,其中有个CSDN中的设计模式博客专栏也是研究的Gof的书籍,通俗易懂,让读者对设计模式一目了然。 自己在学习设计模式的过程中,有时候理解一个设计模式挺简单的,但是想要记住它,运用它,往往比较困难,所以系列文章的主要目的就是让设计模式不单单只是以一个软件模式存在于我们的认知中。更多的是想让读者包括我自己
读者可能还记得本系列博客(二)和(六)中 tf.nn 模块,其中最关心的是 conv2d 这个函数。 首先将博客(二) MNIST 例程中 convolutional.py 关键源码列出: def model(data, train=False): """The Model definition.""" # 2D convolution, with 'SAME' padding (i.e. the output feature map has # the same size as the input).
0、先把页面调用代码贴出来好了 var historyWebsocket = null ; // var websocketOnline = null; //判断当前浏览器是否支持WebSocket % Properties props = PropUtils.getProps(); String url=props.getProperty( "webSocketIp" ); % if ( 'WebSocket' in window){ historyWebsocket = new WebSocket(

第三部分:内存管理 - 2016-06-08 17:06:58

第三部分 内存管理 第8章 内存管理 8.1 背景 内存 :是现代计算机运行中心。内存由很大一组字或字节组成,每个字或字节都有他们自己的地址。CPU根据程序计数器(PC)值从内存中提取指令,这些指令可能会引起进一步对特定内存地址的读取和写入。 8.1.1 基本硬件 CPU所能访问的存储器只有内存和处理器内的寄存器; 保证物理内存的相对速度: 高速缓存(cache) [kæʃ]:CPU和内存之间增加高速内存; 确保操作系统不被用户进程所访问,以及确保用户进程不被其他用户进程所访问。其可通过硬件来实现。 首先
上一篇文章我们谈论了保存点的相关内容,其中就谈到了保存点状态的存储。这篇文章我们来探讨用户程序状态的存储,也是在之前的文章中多次提及的 state backend (中文暂译为 状态终端 )。 基于数据流API而编写的程序经常以各种各样的形式保存着状态: 窗口收集/聚合元素(这里的元素可以看作是窗口的状态)直到它们被触发 转换函数可能会使用 key/value 状态接口来存储数据 转换函数可能实现 Checkpointed 接口来让它们的本地变量受益于 fault tolerant 机制 当检查点机制工作

第二部分:进程管理 - 2016-06-08 17:06:37

第二部分:进程管理 进程 :进程可以看做正在执行的程序。进程需要一定的资源来完成更其任务。 进程是大多数系统中的工作单元。这样的系统有一组进程组成操作系统进程执行系统代码,用户进程执行用户代码,所有进程可以并发执行。 第三章: 进程 3.1 进程概念 程序是被动实体,进程是活动实体,它有一个程序计数器用来表示下一个要执行的命令和相关资源集合。 进程的状态 : 新的:进程正在被创建 运行:指令正在被执行 等待:进程等待某个事件的发生(如I/O完成或收到信号) 就绪:进程等待分配处理器 终止:进程完成执行 重

[置顶] 常见的排序算法 - 2016-06-08 17:06:19

描述: 排序算法可谓数据结构模块中的重中之重,常见的哈希表,二叉树,搜索树/平衡树,位图等数据结构只是处理实际问题的抽象方法,实际在处理接受或生成的数据集时,排序算法显得尤其重要,排序算法家族很庞大,其中包括了冒泡排序,选择排序,插入排序,堆排序,快速排序,归并排序,基数排序,计数排序,希尔排序,箱排序,树型排序等众多算法,每种排序都有各自的特性,没有好坏之分,只有在特定的场景使用合适的排序算法才是上策,单纯的来比显得太过绝对,没有可比性。因为实际需求及各方面条件的限制使得排序算法的可选范围往往只缩小到某

粗浅看 java反射机制 - 2016-06-08 14:06:39

什么是  Java 反射是 Java 被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运 行时透过 Reflection APIs 取得任何一个已知名称的class 的内部信息,包括其 modifiers( 诸如 public, static 等 )、superclass (例如 Object)、 实现之 interfaces(例如 Cloneable),也包括 fields 和 methods 的所有信息,并可于运行时改变 fields 内容或唤起 methods。 Java 反射机制容许程

第四部分:存储管理 - 2016-06-08 14:06:03

第四部分:存储管理 第10章 文件系统接口 文件系统:提供了在线存储和访问计算机操作系统和所有用户的程序与数据机制。文件系统由:文件和目录结构组成。 10.1 文件概念 文件 :操作系统提供的信息存储的统一接口。操作系统对存储设备的各种属性加以抽象,从而定义了逻辑单元(文件),再将文件映射到物理设备上。 文件是记录在外存上的相关信息的具有名称的集合。从用户角度而言,文件是逻辑外存的最小份分配单元。 10.1.1 文件属性 文件属性 : 名称 标识符 类型 位置 大小 保护 时间、日期和用户标识 10.1.