设计模式学习笔记之观察者模式
设计模式学习笔记之观察者模式
潇潇王子 发表于2年前
设计模式学习笔记之观察者模式
  • 发表于 2年前
  • 阅读 2
  • 收藏 0
  • 点赞 2
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: 设计模式学习笔记之观察者模式

观察者模式

    定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。

    观察者模式中,分为两种模式。

    模式,即主题对象向观察者对象推送状态值,不管观察者对象是否需要,并且推送全部数据或者部分数据。

    模式,即主题对象通知观察者对象状态值已改变,观察者根据自己需要决定是否主动到主体对象中获取详细信息。

    两种模式的比较

    1、推模型是假定主题对象知道观察者需要的数据;而拉模型是主题对象不知道观察者具体需要什么数据,没有办法的情况下,干脆把自身传递给观察者,让观察者自己去按需要取值。

    2、推模型可能会使得观察者对象难以复用,因为观察者的update()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能提供新的update()方法,或者是干脆重新实现观察者;而拉模型就不会造成这样的情况,因为拉模型下,update()方法的参数是主题对象本身,这基本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要。

 

    说明:

    1、观察者模式将观察者和主题(被观察者)的对象分离开,实现了两者的松耦合。提高了应用程序的可维护性和重用性;

    2、JAVA API 内置有观察者模式。位于java.util包,包含有最基本的Observer接口与Observable类,分别对应观察者和主题;

    3、主题仅需要把实时的状态值更新给观察者即可,而不需要知道观察者怎样处理数据或者其他细节。

    场景:

    1、对于一个对象的状态值需要实时更新到其他任何几个对象。如气象站检测的天气数据,要实时更新给气象网站的布告板。

/**

 * 主题类接口。

 * 用来定义注册观察者、移除观察者、通知更新等方法

 * @author xiabaike

 */

public interface Subject {

 

    /**

     * 注册观察者

     * */

    public void registerObserver(Observer o);

 

    /**

     * 移除观察者

     * */

    public void removeObserver(Observer o);

 

    /**

     * 当状态改变时,调用此方法,通知所有观察者

     * */

    public void notifyObservers();

}

/**

 * 观察者类接口。

 * 当主题状态发生改变时,主题会把这些状态值当做方法的参数,传送给观察者。

 * @author xiabaike

 * */

public interface Observer {

 

    /**

     * 当主题状态发生改变时,主题会把这些状态值当做方法的参数,传送给观察者

     * 所有观察者都必须实现此方法,以实现观察者接口

     * */

    public void  update(float temp, float humidity, float pressure);

 

}

/**

 * 展示。在布告板上显示内容 

 * */

public interface DisplayElement {

 

    /**

     * 当布告板需要显示时,调用此方法

     * */

    public void display();

 

}

/**

 * 天气数据类。产生更新状态值,并通知布告板观察者

 * */

public class WeatherData implements Subject{

 

    // 用来存放所有的观察者

    private List<Observer> observerList;

 

    private float tempPerature;

    private float humidity;

    private float pressure;

 

    public WeatherData() {

        observerList = new ArrayList<Observer>();

    }

 

    public void registerObserver(Observer o) {

        observerList.add(o);

    }

 

    public void removeObserver(Observer o) {

        if(observerList.contains(o)) {

            observerList.remove(o);

        }

    }

 

    public void notifyObservers() {

        for(int i = 0; i < observerList.size(); i++) {

            observerList.get(i).update(tempPerature, humidity, pressure);

        }

    }

 

    /**

     * 当从气象站得到更新观测值时,通知观察者

     * */

    public void setMeasurements(float temperature, float humidity, float pressure) {

        this.tempPerature = temperature;

        this.humidity = humidity;

        this.pressure = pressure;

        notifyObservers();

    }

}

/**

 * 具体布告板实现类。获取状态值,并展示

 * */

public class CurrentConditionsDisplay implements Observer, DisplayElement{

 

    private float tempPerature;

    private float humidity;

    private float pressure;

    private Subject subject;

 

    public CurrentConditionsDisplay(Subject subject) {

        this.subject = subject;

        this.subject.registerObserver(this);

    }

 

    public void update(float temp, float humidity, float pressure) {

        this.tempPerature = temp;

        this.humidity = humidity;

        this.pressure = pressure;

        display();

    }

 

    public void display() {

        System.out.println("Current conditions: " + tempPerature +", "+ humidity +", "+ pressure);

    }

}

/**

 * 主类,模拟气象站产生检测数据,并更新给布告板

 * */

public class WeatherStation {

 

    public static void main(String[] args) {

        WeatherData subject = new WeatherData();

        CurrentConditionsDisplay observer = new CurrentConditionsDisplay(subject);

        subject.setMeasurements(1, 2, 3);

    }

}

 

 

参考资料:《Head First 设计模式》

                   http://www.cnblogs.com/itTeacher/archive/2012/12/03/2800129.html

                   http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html

共有 人打赏支持
粉丝 2
博文 1
码字总数 1071
×
潇潇王子
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: