观察者模式
&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不得不说的故事...
浙公网安备 33010602011771号