设计模式之--观察者模式(一)

2014-11-24 07:26:00 · 作者: · 浏览: 2

网上对设计模式的分享和笔记已经很多了,我依然在此写这一篇十分没有新意的东西,这主要是一来记录下自己最近一段时间的学习生活,另一来是希望通过这篇博文来重新启动一下自己的博客灌水生活,很久没有写东西了,看着尘封已久的博客、回首那段记忆空白的日子,有点惶恐的感觉,这么长的时间我竟连一点痕迹都没留下,我这样的存在实在是太过于环保了。好吧,废话就此打住,让我们进入主题。


1.什么是观察者模式

按照《Head First Design Pattern》的定义,观察者模式用于定义一种对象之间的一对多的关系,使得其中的某一个对象发生变化时,其他对此感兴趣的对象能被通知,并自动更新状态。

\

在观察者模式中,有一个被观察主体(Subject)用于发布(Publish)状态(State),此外还有多个观察者对象(Observer Object)。观察者对象通过向被观察主体注册或者订阅(Register or Subscribe)表示自己对Subject发布的状态感兴趣。Subject对象定时(根据自身状态的改变)主动将状态信息告知Observer对象(push方式)或者通知观察者对象取其所感兴趣的信息(pull方式)。

观察者模式中,Subject不关心Observer的实现方式,不关心Observer的加入和退出;Observer对象也不关心Subject的实现方式,只要求其实现了特定的接口,能提供其感兴趣的信息。


2. 应用场景

观察者模式又名发布者模式,顾名思义这种模式主要运用在当一种对象需要对外发布状态时,主要运用在对象之间存在多对一的依赖关系时候,让多个观察者对象能够根据被观察主体状态的改变自动更新(update)自己。


3. 实现方式

在观察者模式的设计实现中,由于要求彼此之间的松耦合,彼此不再关心对方的具体实现,只要求对方实现特定的接口即可。因此,要求观察者主体(Subject)具体实现类必须实现Subject接口,而观察者对象(Observer)具体实现类必须Observer接口。原谅我没有找到画类图的工具,所以我借用网上的一张图片以表示这种关系。

\

(观察者模式结构,引自supercrsky)

Subject接口定义了三个方法,分别是attatch(向Subject注册观察者)、detach(从注册的观察表中删除)、notifyObservers(通知观察者对象)。Observer接口定义了一个方法update,用于接收Subject的更新调用。在Subject具体类的实现中因为需要维持观察者的信息,所以需要定义一个List用于保存所有的观察者对象引用。

下面通过一个简单的例子向大家讲一下观察者模式的具体实现,在本例子中被观察者主体在感知到自身的状态(message)发生变化之后,将消息发送给所有的观察者对象。本例中定义了三种不同的观察者实现类,他们以不同的方式展现接收到的消息,分别是原样展示、转化成大写展示,转换成小写展示。

---------------- Subject.java

package cn.ac.ict.chengenbao;

public interface Subject {
	public void registerObserver(Observer obj);
	public void removeObserver(Observer obj);
	public void notifyObservers();
}

----------------- Observer.java

package cn.ac.ict.chengenbao;

public interface Observer {
	public void update(String message);
}

--------------------- SubjectImpl.java

package cn.ac.ict.chengenbao;

import java.util.ArrayList;
import java.util.List;

public class SubjectImpl implements Subject {
	private List
  
    observerList = null;
	private String msg = null;
	
	public SubjectImpl() {
		observerList = new ArrayList
   
    (); } public void registerObserver(Observer obj) { // TODO Auto-generated method stub observerList.add(obj); } public void removeObserver(Observer obj) { // TODO Auto-generated method stub observerList.remove(obj); } public void notifyObservers() { // TODO Auto-generated method stub for( Observer o : observerList) { o.update(msg); } if ( observerList.size() == 0 ) { System.out.println("There is no observers in the list."); } } public void changeMessage(String message) { msg = message; this.notifyObservers(); } } 
   
  

------------------------ OriginOutputer.java

package cn.ac.ict.chengenbao;

public class OriginOutputer implements Observer {
	private Subject subject = null;
	
	public OriginOutputer(Subject s) {
		subject = s;
		s.registerObserver(this);
	}

	public void update(String message) {
		// TODO Auto-generated method stub
		this.display(message);
	}
	
	private void display(String message) {
		System.out.println(this.getClass().getName() + ":" + message);
	}
	
	public void leave() {
		this.display("I remove myself from the ObserverList...");
		subject.removeObserver(this);
	}

}

----------------------- UpperOutputer.java

package cn.ac.ict.chengenbao;

public class UpperOutputer implements Observer {
	private Subject subject = null;
	
	public UpperOutputer(Subject s) {