设计模式学习笔记--观察者(Observer)模式(一)

2014-11-23 23:26:36 · 作者: · 浏览: 2


写在模式学习之前


什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式;每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案;当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式。

设计模式就是抽象出来的东西,它不是学出来的,是用出来的;或许你根本不知道任何模式,不考虑任何模式,却写着最优秀的代码,即使以“模式专家”的角度来看,都是最佳的设计,不得不说是“最佳的模式实践”,这是因为你积累了很多的实践经验,知道“在什么场合代码应该怎么写”,这本身就是设计模式。

有人说:“水平没到,学也白学,水平到了,无师自通”。诚然,模式背熟,依然可能写不出好代码,更别说设计出好框架;OOP理解及实践经验到达一定水平,同时也意味着总结了很多好的设计经验,但"无师自通",却也未必尽然,或者可以说,恰恰是在水平和经验的基础上,到了该系统的学习一下“模式”的时候了,学习一下专家总结的结果,印证一下自己的不足,对于提高水平还是很有帮助的。

本系列的设计模式学习笔记,实际是对于《Java与模式》这本书的学习记录。


观察者模式的定义


观察者模式,又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式、从属者(Dependerts)模式。

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


观察者模式的 结构


结构图


\


所涉及的角色


(1)抽象主题(Subject)角色:主题角色吧所有对观察者对象的引用保存在一个聚集(比如Vector对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,主题角色又叫做抽象被观察者(Observable)角色,一般用一个抽象类或者一个接口实现。

(2)抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口叫做更新接口。抽象观察者角色一般用一个抽象类或者一个接口实现。

(3)具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者角色(Concrete Observable)。具体主题角色通常用一个具体子类实现,负责实现如何 引用观察者的聚集的管理办法。

(4)具体观察者(ConcreteObserver)角色:存储于主题的状态自洽的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体观察者角色可以保存一个指向具体主题对象的引用。具体观察者角色通常用一个具体子类实现。


代码实现

import java.util.*;
interface Subject
{
	//调用这个方法登记一个新的观察者对象
	void attach(Observer observer);
	//调用这个方法删除一个登记过的观察者对象
	void detach(Observer observer);
	//调用这个方法通知所有登记过的观察者对象
	void notifyObservers();
}
class ConcreteSubject implements Subject
{
	private Vector observersVector = new Vector();
	public void attach(Observer observer)
	{
		observersVector.addElement(observer);
	}
	public void detach(Observer observer)
	{
		observersVector.removeElement(observer);
	}
	public void notifyObservers()
	{
		Enumeration e = observers();
		while(e.hasMoreElements())
		{
			((Observer)e.nextElement()).update();
		}
	}
	public Enumeration observers()
	{
		return ((Vector)observersVector.clone()).elements();
	}
}
interface Observer
{
	void update();
}
class ConcreteObserver implements Observer
{
	public void update()
	{
		System.out.println("I am notified");
	}
}


JDK对观察者模式的支持

JDK提供了java.util.Observable类和Observer接口,构成Java语言对观察者模式的支持。下面演示一个使用这两个接口/对象的例子。


结构图


\


代码实现


import java.util.Observer;

import java.util.Observable;
class Tester
{
	private static Watched watched;
	private static Observer watcher;
	public static void main(String[] args)
	{
		//创建被观察者对象
		watched = new Watched();
		//创建观察者对象,并将被观察者对象登记
		watcher = new Watcher(watched);

		//给给观察者对象的状态赋值2次
		watched.changeData("I am Tom");
		watched.changeData("I am Jack");
	}
}
class Watched extends Observable
{
	private String data = "";
	public String retrieveData()
	{
		return data;
	}
	public void changeData(String data)
	{
		if(!this.data.equals(data))
		{
			this.data = data;
			setChanged();
		}
		notifyObservers();
	}
}
class Watcher implements Observer
{
	public Watcher(Watched w)
	{
		w.addObserver(this);
	}
	public void update(Observable ob,Object arg)
	{
		System.out.println("Data has been changed to: '" + ((Watched)ob).retrieveData() + "'");
	}
}


Observable源码


我们也来看看JDK源码:jav