设计模式之观察者模式

1、概念(百科)

观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

2、实现方式

观察者模式包含有两个角色:观察者(Observer)和目标者[/被观察者](Subject),二者之间存在“观察”的逻辑关联,当目标状态发生变化时,所有依赖于目标的对象都会得到通知并自动刷新。

3、大致过程

wKioL1doJw6hVvFnAAAymxnJzuI492.jpg-wh_50

涉及角色:

3.1 目标者(Subject)抽象类,包括对观察者的注册,撤销和发送通知

3.2 具体目标(ConcreteSubject)记录目标者的相关状态。在状态更新时,通知所有注册在本目标的观察者

3.3 观察者(Observer)为所有观察者定义一个接口,得到状态更新时更新自己

3.4 具体观察者(ConcreteObserver)实现抽象观察者所要求的更新接口,以便使本身的状态和主题状态协调


4、相关代码

4.1 目标者代码

import java.util.ArrayList;

import java.util.List;


public abstract class Subject {

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


public void attach(Observer observer) {

this.observers.add(observer);

}


public void dettach(Observer observer) {

this.observers.remove(observer);

}


protected void notifyObservers() {

for(Observer observer:observers){

observer.update(this);

}

}


}


public class ConstreteSubject extends Subject {

//目标对象的状态

private String subjectState;

/**

* @return the subjectState

*/

public String getSubjectState() {

return subjectState;

}


/**

* @param subjectState the subjectState to set

*/

public void setSubjectState(String subjectState) {

this.subjectState = subjectState;

this.notifyObservers();

}


}


4.2 观察者代码

public interface Observer {

/**

* 更新的接口

* @param subject传入目标对象,方便获取响应的目标对象的状态

*/

public void update(Subject subject);


}



public class ConstreteObserver implements Observer {

/**

     * 获取目标类的状态同步到观察者的状态

     */

@Override

public void update(Subject subject) {

   System.out.println("观察者收到目标者的更新状态是:" + ((ConstreteSubject)subject).getSubjectState());

}


}

以上描述了观察者模式的具体实现,目前JDK已经提供该模式的实现标准,在使用过程中,不需要再像上面一样完成自己实现整个过程,只需要实现java.util.Observable接口即可。

5、JDK标准实现

模拟一个场景,瑞士公投全球最高底薪标准,假如公投通过,作为老板和员工的反应肯定是不一样的,此处公投内容为目标者或者叫被观察者,老板和雇员作为观察者。看具体代码

5.1 目标

import java.util.Observable;


//公投目标的具体实现类

public class ConcreteSubject extends Observable {

    //公投的具体内容

private String content;


/**

* @return the content

*/

public String getContent() {

return content;

}


/**

* @param content the content to set

*/

public void setContent(String content) {

this.content = content;

//通知所有的观测者

//注意在通知之前,在用JAVA的Observer模式,下面这句不可少

this.setChanged();

//主动通知,推实现

this.notifyObservers(this.content);

//拉方式,不带参数

//this.notifyObservers();

}

}


5.2 观察者

import java.util.Observable;

import java.util.Observer;


public class ConcreteObserver implements Observer {

//观察者名称

private String ObserverName;


@Override

public void update(Observable arg0, Object arg1) {

//推

if("老板".equals(this.ObserverName)){

System.out.println(this.ObserverName + "接到最低时薪公投结果:" + arg1 + ",大骂:F**k成本上升了。。。");

}else if("雇员".equals(this.ObserverName)){

System.out.println(this.ObserverName + "接到最低时薪公投结果:" + arg1 + ",开心:^_^ 收入增加了。。。");

}

}


/**

* @return the observerName

*/

public String getObserverName() {

return ObserverName;

}


/**

* @param observerName the observerName to set

*/

public void setObserverName(String observerName) {

ObserverName = observerName;

}


}


5.3 测试类


public class Client {


public static void main(String[] args) {

//被观察者

ConcreteSubject subject = new ConcreteSubject();

//观察者

ConcreteObserver boss = new ConcreteObserver();

boss.setObserverName("老板");

//观察者

ConcreteObserver emp = new ConcreteObserver();

emp.setObserverName("雇员");

//注册观察者

subject.addObserver(boss);

subject.addObserver(emp);

//公投结果

subject.setContent("通过");


}


}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章