7days

快乐工作,快乐生活!
观察者模式

&quo

(Gof定义)观察者模式,定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新,也被称为发布-订阅(Publish-Subscribe)。想必很多都用过rss新闻聚合吧,例如小张和小李订阅了sina rss,那么sina rss可称为Observable(被观察者)或subject,小张和小李就是observer.当sina rss内容更新时会通知小张和小李。我们用一个简单的小程序模拟这个过程。

1.Subject

t;>   -subject知道它的观察者。可以有任意多个观察者观察同一个subject。

   -提供注册和删除观察者对象的接口。

//Subject.java ,定义了subject接口

package org.days7.subject;

import org.days7.observer.Observer;

public interface Subject
{
	//注册观察者对象
	public void regiterObserver(Observer o);
	//移除观察者对象
	public void removeObserver(Observer o);
	//通知每一个观察者,状态已变化
	public void notifyObservers();
}

2.Observer  -为那些在subject发生改变时需获得通知的对象定义一个更新接口。 //Observer.java,Observer接口定义了一个update方法,供observer对象实现,更新状态

package org.days7.observer;

public interface Observer
{
	//当subject对象状态变化时,更新观察者对象
	public void update();
}
 

3.ConcreteSubject
   -将有关状态存入各ConcreteObserver对象。
   -当它的状态发生改变时, 向它的各个观察者发出通知。

//SinaRss.java,实现Subject接口,注册观察者并在状态改变时通知观察者

package org.days7.subject;

import java.util.ArrayList;
import java.util.Iterator;
import org.days7.observer.Observer;

public class SinaRss implements Subject
{
	//建一个list用来保存Observer对象
	private ArrayList<Observer> observerList = null;
	private String text = null;
	
	//构造函数,new一个list
	public SinaRss()
	{
		observerList = new ArrayList<Observer>();
	}
	
	//当subject状态变化时,通知每一个观察者
	@Override
	public void notifyObservers()
	{
		Iterator<Observer> it = observerList.iterator();
		while(it.hasNext())
		{
			Observer observer = it.next();
			observer.update(); //更新observer的状态
		}
	}
	
	//注册观察者对象
	@Override
	public void regiterObserver(Observer o)
	{
		observerList.add(o);
	}
	
	//移除一个观察者对象
	@Override
	public void removeObserver(Observer o)
	{
		observerList.remove(o);
	}
	
	//更新状态,并通知每一个观察者
	public void setNewText(String text)
	{
		this.text = text;  //持有更新状态的引用
		notifyObservers(); //通知观察者,状态已变化
	}
	
	//返回该主题的更新状态,方便观察者获取它想要的东西
	public String getNewText()
	{
		return this.text;  //返回subject状态
	}

}

 

4.ConcreteObserver(具体观察者) 
  -持有一个指向ConcreteSubject对象的引用。 
  -存储有关状态,这些状态应与Subject的状态保持一致。 
  -实现Observer的更新接口以使自身状态与Subject的状态保持一致。

// Subscriber.java,具体的Observer,实现Observer接口,根据Subject的变化更新自己的状态

package org.days7.observer;

import org.days7.subject.SinaRss;
import org.days7.subject.Subject;

public class Subscriber implements Observer
{
	//更新的内容(subject状态)
	private String text = null;
	//在observer对象中保留一个具体的subject对象引用,用来获取更新的内容
	private SinaRss rss = null;
	
	//构造函数,传入具体的subject对象,持有该对象的引用
	public Subscriber(Subject subject)
	{
		if(subject instanceof SinaRss)
		{
			this.rss = (SinaRss)subject;
		}
		this.rss.regiterObserver(this);//注册观察者对象
	}
	
	//重写observer的update方法
	@Override
	public void update()
	{
		this.text = this.rss.getNewText();//获取更新的新闻内容(更新的状态)
		displayText(); //对更新的状态进行操作,显示更新的内容
	}
	
	//显示更新内容
	private void displayText()
	{
		System.out.println("更新新闻:"+this.text);
	}

}

下面来测试一下这个小程序:

//test.java, 测试程序

package org.days7.test;

import org.days7.observer.Subscriber;
import org.days7.subject.SinaRss;

public class Test
{

	/**
	 * 测试程序
	 */
	public static void main(String[] args)
	{
		SinaRss rss = new SinaRss();
		Subscriber sub = new Subscriber(rss);
		String text1 = "New Superstar : 小蝴蝶大战外星人";
		rss.setNewText(text1);
		String text2 = "我和java不得不说的故事...";
		rss.setNewText(text2);
	}

}

Console:
更新新闻:New Superstar : 小蝴蝶大战外星人
更新新闻:我和java不得不说的故事...

posted on 2010-05-29 12:01  7days  阅读(234)  评论(0编辑  收藏  举报