zoukankan      html  css  js  c++  java
  • 设计模式学习笔记之观察者模式

    观察者模式
        定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。
        观察者模式中,分为两种模式。
        模式,即主题对象向观察者对象推送状态值,不管观察者对象是否需要,并且推送全部数据或者部分数据。
        模式,即主题对象通知观察者对象状态值已改变,观察者根据自己需要决定是否主动到主体对象中获取详细信息。
        两种模式的比较

        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 设计模式》
  • 相关阅读:
    Lambda表达式效率问题
    设计模式之代理模式
    spring学习之AOP
    jq 中input为radio设置选中状态,attr问题
    css 清除float浮动方法整理
    jquery.ready可以在文档加载后尽快执行对文档的操作
    前端学习网址整理
    图片缓存未触发onload
    spring mvc 下,ajax调用后台controller方法时报415 (Unsupported Media Type)错误
    nodejs向前台send数据时Date类型数据格式问题
  • 原文地址:https://www.cnblogs.com/LeslieXia/p/5494800.html
Copyright © 2011-2022 走看看