版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wode_dream/article/details/49124207
应用场景举例:观察者模式就类似于日常生活中订阅报纸,当你订阅了报纸后,报社每次出版新的报纸,都会送到你家。
定义:观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
实现:在Java中观察者模式有两个实现方法,一种是自定义实现,另一种是Java内置观察者。下面分别分析下两种实现方法。
设计原则:1、为了交互对象之间的松耦合设计而努力。
一、自定义实现
1:结构
2:示例代码
接口:
<span style="font-size:18px;">/**
* 主题接口
*/
public interface Subject
{
/**
* registerObserver()与removeObserver()这两个方法都需要一个观察
* 者作为变量,该观察者是用来注册或被删除的。
*/
public void registerObserver(Observer o);
public void removeObserver(Observer o);
/**
* 当主题状态改变时,这个方法会被调用,以通知所有的观察者。
*/
public void notifyObservers();
}
/**
* 观察者接口
*/
public interface Observer
{
/**
* 所有的观察者都必须实现update()方法,以实现观察者接口
* @param testFlag
*/
public void update(int testFlag);
}
public interface DisplayElement
{
//显示方法
public void display();
}</span>
类实现:
<span style="font-size:18px;">/**
* 实现主题接口
*/
public class NewsPaperOffice implements Subject //实现Subject接口
{
private ArrayList observers;
private int testFlag;
public NewsPaperOffice()
{
observers=new ArrayList();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i=observers.indexOf(o);
if(i>=0)
{
observers.remove(i);
}
}
@Override
public void notifyObservers()
{
for(int i=0;i<observers.size();++i)
{
Observer observer=(Observer)observers.get(i);
observer.update(testFlag);
}
}
/**
* 当testFlag更新时通知观察者
*/
public void testFlagChanged()
{
notifyObservers();
}
public void setTestFlag(int testFlag)
{
this.testFlag=testFlag;
}
}
/**
* 显示类实现Observer接口,所以可以从NewsPaperOffice中获得数据;
* 所有显示类必须实现DisplayElement接口。
*/
public class CurrentCoditionsDisplay implements Observer,DisplayElement
{
private int testFlag;
private Subject newsPaperOffice;
/**
* 构造器需要NewsPaperOffice对象作为注册之用
* @param newsPaperOffice
*/
public CurrentCoditionsDisplay(Subject newsPaperOffice)
{
this.newsPaperOffice=newsPaperOffice;
newsPaperOffice.registerObserver(this);
}
@Override
public void display() {
System.out.println("CurrentCodition testFlag="+testFlag);
}
@Override
public void update(int testFlag) {
this.testFlag=testFlag;
display();
}
}
public class ObserveMode
{
public static void main(String[] args)
{
NewsPaperOffice newsPaperOffice=new NewsPaperOffice();
CurrentCoditionsDisplay currentDisplay=new CurrentCoditionsDisplay(newsPaperOffice);
newsPaperOffice.setTestFlag(2);
newsPaperOffice.setTestFlag(10);
}
}</span>
二、Java内置观察者模式
1:结构
注意:此处的Observable不是接口而是一个类。
2:示例代码
<span style="font-size:18px;">public class NewsPaperOffice extends Observable //此处使用java.util.Observable
{
private int testFlag;
public NewsPaperOffice(){ } //构造器不再需要为了记住观察者们而建立数据结构
public void testFlagChanged()
{
setChanged(); //在调用notifyObservers()之前, 要先调用setChanged()来指示状态已经改变
notifyObservers();
}
/**
* 观察者通过这种方法取得NewsPaperOffice对象的状态
* @return
*/
public int getTestFlag()
{
return testFlag;
}
public void setTestFlag(int testFlag)
{
this.testFlag=testFlag;
}
}
public class GeneralDisplay implements Observer,DisplayElement //此处用的是java.util.Observer
{
Observable observable;
private int testFlag;
public GeneralDisplay(Observable observable)
{
this.observable=observable;
observable.addObserver(this);
}
@Override
public void display() {
System.out.println("testFlag="+testFlag);
}
@Override
public void update(Observable o, Object arg)
{
if(o instanceof NewsPaperOffice)
{
NewsPaperOffice newsPaperOffice=(NewsPaperOffice)o;
this.testFlag=newsPaperOffice.getTestFlag();
display();
}
}
}
public class DomensticDisplay
{
public static void main(String[] args)
{
NewsPaperOffice newsPaperOffice=new NewsPaperOffice();
GeneralDisplay generalDisplay=new GeneralDisplay(newsPaperOffice);
newsPaperOffice.setTestFlag(3);
newsPaperOffice.testFlagChanged();
}
}</span>
1:内置模式实现通知观察者的顺序是不固定的,而自定义模式顺序是固定的;
2:java.util.Observable是一类,如果Observable有一个别的父类,则会冲突,并且违反了多用组合少用继承的设计原则。