文档章节

观察者模式-常用设计模式

dapengking
 dapengking
发布于 2014/03/03 22:19
字数 1250
阅读 602
收藏 7

观察者模式

    今天记录下,常用设计模式的第二篇-观察者模式。说起来,我知道观察者模式这个名词,在目前我所知道的设计模式中算是比较早的。因为,在之前闲的时候,曾经自学过android开发,在ui设计中的按钮事件,我印象中就是基于观察者模式实现的。你可以创建一个监听器类的对象,实现当按钮被点击时需要进行的动作。然后将这个对象(其实也就所谓的观察者)注册给按钮。这样,当有鼠标点击按钮时,按钮就会通知所有注册了的监听器类对象,调用其中的事件处理方法。

用headfirst设计模式一书中所说的一句话来概括就是:“当有趣的事情发生时,可千万别错过了!”。

    没错,观察者模式可以帮助对象了解运行现况。不会错过该对象感兴趣的事。而且,对象还可以在运行时决定是否需要继续接受通知。

    再引用一个书中的比方。如果了解报纸的订阅是怎么一回事的话,就会好理解的多。因为它们之间根本就是一样的道理,只是名字不太一样罢了。报纸的出版者就是观察者模式中的“主题(Subject)”,而报纸的订阅者其实也就是我们所谓的“观察者”。

严格的定义:观察者模式定义了对象之间一对多的依赖关系,这样一来,当一个对象改变状态的时候,它的所有依赖对象都可以收到通知并且自动更新状态。

观察者模式的UML类图(图片转自百度图片)

稍微解释下上图的意思:


  1. 首先,遵循面向接口而非面向实现编程的原则,我们需要两个接口:主题(Subject)和观察者(Observer)。在主题接口中声明了一般主题类中最基础的三个方法接口,分别为注册观察者(registerObserver)、删除观察者(removeObserver)和通知观察者(notifyObserver)。而观察者接口中通常至少会声明update方法接口,update将来的实现,用来在观察者收到主题的通知后,作出具体的动作;
  2. 接着,应该实现ConcreteSubject类,并实现Subject接口中的方法。通常情况下,在ConcreteSubject类中会维护一个Observer的容器,用来盛放注册进来的观察者对象的引用;
  3. 最后,当ConcreteSubject类的对象感知到状态改变后,会调用notifyOBserver()方法,在notifyOBserver()的实现中,我们会遍历ConcreteSubject类中Observer的容器中的所有Observer引用,对于每一个引用的对象,调用其update()方法。

通过上面三步的介绍,应该能够比较清楚的理解了观察者模式的基本原理了。在我自己的理解看来,观察者模式,其实与我的上篇帖子中的策略模式的最基本的实现机制相似:也是采用组合的方式,某些对象(这里是观察者对象)的引用组合到某个类(这里指主题类对象)的对象中。当某个事件发生时,主题类对象会采用一定的算法(这个算法不确定,最简单的方式是采用数组作为容器,然后采用遍历数组的方式。)遍历所有的观察者对象引用,并逐一调用update()方法。

与策略模式设计的初衷虽然不同(1.策略模式是为了封装经常变化的逻辑,将经常变动的代码,从比较稳定的代码中剥离出来,从而实现代码复用,并且可以实现在程序运行时的动态组合,提高了程序的灵活性。2.而这里的观察者模式则是为了实现消息的灵活订阅,这种一对多的关系)。但是它们之间在实现上的区别很小,都是通过组合的方式实现的。

一段简单的代码:


package observer;

public interface Subject {

	public void registerObserver(Observer o);
	public void removeObserver(Observer o);
	public void notifyObserver();
	
}



package observer;

public interface Observer {
	public void update();
}



package observer;

import java.util.ArrayList;

public class ConcreteSubject implements Subject {

	private ArrayList<Observer> observers = new ArrayList<Observer>();
	
	@Override
	public void notifyObserver() {
		for (Observer observer : observers) {
			observer.update();
		}
	}

	@Override
	public void registerObserver(Observer o) {
		observers.add(o);
	}

	@Override
	public void removeObserver(Observer o) {
		observers.remove(o);
	}

}



package observer;

public class ConcreteObserver implements Observer {

	private String title = null;
	
	public ConcreteObserver(String title,Subject s) {
		this.title = title;
		s.registerObserver(this);
	}

	@Override
	public void update() {
		//观察者收到消息后的处理逻辑
		//
		//
		System.out.println(title + "收到了通知,并且相应了");
	}

}
//测试方法类
package observer;

public class Main {

	public static void main(String[] args) {
		Subject s = new ConcreteSubject();
		
		new ConcreteObserver("observer1",s);
		new ConcreteObserver("observer2",s);
		
		//模拟有事件发生时,调用notifyObserver()方法
		s.notifyObserver();
	}
}




运行结果:


--the end~




© 著作权归作者所有

共有 人打赏支持
dapengking
粉丝 7
博文 133
码字总数 53553
作品 0
东城
程序员
JavaScript设计模式之观察者模式

前言 准备研究一下MVVM的一些东西,由于MVVM运用了观察者模式的思想,因此翻开了《JavaScript设计模式与开发实践》一书,将观察者模式学习了一遍,顺便有对一些常用的设计模式进行一些了解,...

Srtian
05/22
0
0
Java设计模式 create FactoryMethod

工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。 为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经...

神勇小白鼠
2011/05/18
0
0
JavaScript常用设计模式

设计模式 设计模式是一种在长时间的经验与错误中总结出来可服用的解决方案。 设计模式主要分为3类: 创建型设计模式:专注于处理对象的创建 Constructor构造器模式,Factory工厂模式,Singl...

a独家记忆
07/13
0
0
代理模式(Proxy Pattern):动态代理 - 最易懂的设计模式解析

前言 今天我来全面总结开发中最常用的设计模式 - 代理模式中的动态代理模式 其他设计模式介绍 1分钟全面了解“设计模式” 单例模式(Singleton) - 最易懂的设计模式解析 简单工厂模式(Sim...

Carson_Ho
04/09
0
0
javascript 设计模式之工厂(Factory)模式

工厂模式介绍 工厂模式是一个创建型的模式,主要就是创建对象。其中工厂模式又分为简单工厂模式和抽象工厂模式。简单工厂模式是通过工厂方法确定创建 对应类型的对象。抽象工厂模式是通过子类...

hlxiong
2014/04/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

go语言学习总结

一、描述 go语言是直接将源码编译成二进制机器码的语言;它支持面向对象、也支持函数式编程;支持并发很容易; 二、基本语法学习路径 https://studygolang.com/subject/2...

盼望明天
23分钟前
1
0
JSP 九大内置对象及其作用域

JSP 中一共预先定义了 9 个这样的对象,分别为:request、response、session、application、out、pagecontext、config、page、exception ,下面就简单介绍下。 1、request 对象 request 对象...

几个栗子
34分钟前
0
0
Java中的坑之方括号

Java中的坑之方括号 这一段时间,在做项目的时候,发现了一个坑,这个坑说大不大,说小不小,不知道的足够喝一壶,知道的就可以轻松解决。 问题描述 在做数据统计的时候,遇见了如下形式的数...

星汉
45分钟前
1
0
[雪峰磁针石博客]python机器学习、web开发等书籍汇总

Building Machine Learning Systems with Python Third Edition - 2018.pdf 下载地址 Get more from your data by creating practical machine learning systems with Python Key Features ......

python测试开发人工智能安全
56分钟前
1
0
文件的压缩与解压(linux)

Linux下*.tar.gz文件解压缩命令 1.压缩命令:   命令格式:tar -zcvf 压缩后文件名.tar.gz 被压缩文件名 可先切换到当前目录下。压缩文件名和被压缩文件名都可加入路径。 2.解压缩命令: ...

qimh
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部