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

来源:互联网 发布:windows 10显卡是多少 编辑:程序博客网 时间:2024/05/16 13:40

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

观察者模式

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

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;@Overridepublic void registerObserver(Observer observer) {// TODO Auto-generated method stubobserverList.add(observer);}@Overridepublic void removeObserver(Observer observer) {// TODO Auto-generated method stubif(observerList.contains(observer)){observerList.remove(observer);}}@Overridepublic void notifyObserver() {// TODO Auto-generated method stubfor(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);}@Overridepublic 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中使用最多的设计模式之一,在观察中模式中我们使用了松耦合设计和面向接口编程原则。观察者模式让主题和观察者之间变的松耦合。根据面向接口编程原则,主题只需要知道观察者实现的是什么接口,不需要了解具体实现细节,只要某一个对象实现了观察者接口,我们就可以动态的增加和删除观察者;而且如果增加了不同类型的观察者,我们也不需要更改主题中的代码。

如果我们在其它地方需要使用观察者或主题,可以轻易的复用,改变主题的一方或者另一方,并不会相互影响。因为两者是松耦合的,只要主题和观察者遵守接口规范,我们就可以自由的改变具体的实现类。


0 0
原创粉丝点击