您的位置:首页 > 其它

大话设计模式之观察者模式

2017-04-21 10:44 260 查看


大话设计模式之观察者模式

观察者模式

为了了解观察者模式,我们首先看下报纸的订阅是怎么回事:

1、报社的业务是出版报纸。

2、向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的客户,你就会一直收到报纸。

3、当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来。

4、只要报社还在运营,就会一直有人向他们订阅报纸或取消订阅报纸。

一个报社有多个订阅者,报社有新报纸更新,会自动把新报纸推送给订阅者。订阅者可以订阅和取消订阅。

如果我们了解了报纸的订阅是怎么回事,其实就明白观察者模式的内容,只是具体的称呼有点不一样。把出版社称呼为“主题”(Subject),订阅者称作“观察者”(Observer)。让我们通过图1-1,加深对观察模式的认识。



(图1-1)

观察者模式定义了一系列对象之间的一对多关系。当一个对象改变状态,其他依赖者都会收到通知。主题和观察者之间是一对多的关系。观察者依赖于此主题,只要主题状态一有变化,观察者就会被通知。根据通知的内容,观察者可能因此新值而更新。

实现观察者的方式有很多种,但是以包含Subject和Observer接口的类设计最常见。让我们通过具体的例子,揭开观察者模式神秘的面纱。

二.观察者模式实现

类图



(图2-1)
在观察者模式里,主题是具有状态的对象,并且可以控制这些状态。也就是说,有“一个”具有状态的主题。另一方面,观察者使用这些状态,虽然这些状态并不属于他们。有许多的观察者,依赖主题来告诉他们状态何时改变了。这就产生了一对多的关系,“一个”主题,对“多个”观察者的关系。数据改变后,观察者会收到主题的通知。

具体的代码实现

Subject接口

/**
* 主题接口
* @author lizhizhou
*
*/
public interface Subject {
/**
* 注册观察者
* @param observer
*/
void registerObserver(Observer observer);

/**
* 取消注册
* @param observer
*/
void removeObserver(Observer observer);

/**
* 通知观察者
*/
void notifyObserver();
}


Observer接口

/**
* 观察者接口
* @author lizhizhou
*
*/
public interface Observer {
void update(PaperVO paperVO);
}

PaperVO 数据对象

/**
* 报纸对象
* @author lizhizhou
*
*/
public class PaperVO {
private String title;
private String content;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}

}

ConcreteSubject主题实现类

/**
* 具体的观察者
* @author lizhizhou
*
*/
public class ConcreteSubject implements Subject {

private List<Observer> observerList=new ArrayList<Observer>();

private PaperVO paperVO;

@Override
public void registerObserver(Observer observer) {
// TODO Auto-generated method stub
observerList.add(observer);
}

@Override
public void removeObse
9ea8
rver(Observer observer) {
// TODO Auto-generated method stub
if(observerList.contains(observer)){
observerList.remove(observer);
}
}

@Override
public void notifyObserver() {
// TODO Auto-generated method stub
for(Observer observer:observerList){
observer.update(paperVO);
}
}

/**
* 数据更新
*/
public void changePaper(){
PaperVO paperTemp=new PaperVO();
paperTemp.setTitle("标题");
paperTemp.setContent("内容");
this.paperVO=paperTemp;
//数据更新完成之后,通知观察者
notifyObserver();
}

}


ConcreteObserver具体观察者

/**
* 具体的观察者
* @author lizhizhou
*
*/
public class ConcreteObserver implements Observer {
private Subject subject;
private String observerName;
public ConcreteObserver(Subject subject,String observerName){
this.subject=subject;
this.observerName=observerName;
subject.registerObserver(this);
}
@Override
public void update(PaperVO paperVO) {
// TODO Auto-generated method stub.
if(null!=paperVO){
System.out.println(this.observerName+"已收到更新信息:");
System.out.println(paperVO.getTitle()+";"+paperVO.getContent());
System.out.println("-----------------------------------");
}
}

}

SubjectTest测试代码

public class SubjectTest {
public static void main(String[] args) {
ConcreteSubject subject=new ConcreteSubject();
Observer observerCat=new ConcreteObserver(subject, "小猫");
Observer observerDog=new ConcreteObserver(subject, "小狗");
Observer observerChicken=new ConcreteObserver(subject, "小鸡");
//更新数据
subject.changePaper();
}
}


运行结果:

小猫已收到更新信息:
标题;内容
-----------------------------------
小狗已收到更新信息:
标题;内容
-----------------------------------
小鸡已收到更新信息:
标题;内容
-----------------------------------

三.总结

观察者模式是JDk中使用最多的设计模式之一,在观察中模式中我们使用了松耦合设计和面向接口编程原则。观察者模式让主题和观察者之间变的松耦合。根据面向接口编程原则,主题只需要知道观察者实现的是什么接口,不需要了解具体实现细节,只要某一个对象实现了观察者接口,我们就可以动态的增加和删除观察者;而且如果增加了不同类型的观察者,我们也不需要更改主题中的代码。

如果我们在其它地方需要使用观察者或主题,可以轻易的复用,改变主题的一方或者另一方,并不会相互影响。因为两者是松耦合的,只要主题和观察者遵守接口规范,我们就可以自由的改变具体的实现类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: