• 设计模式 | 第二篇:观察者模式


    观察者模式定义

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

    使用场景

      杂志的发布订阅,微信公众号的通知等

    设计原则

      为了交互对象之间的松耦合设计而努力

    优缺点

      优点:

        1、观察者和被观察者是抽象耦合的。
        2、建立一套监听触发机制。

      缺点:

        1、如果观察者众多,通知所有的观察者会很消耗时间,这里建议异步处理。    

        2、可能出现循环调用。

    UML类图

    示例

      这里应用《Head First设计模式》一书中的例子

    主题(被观察者)接口  

    package com.study.headfirst.oberver;
    
    /**
     * 主题
     * 
     * @author mdl
     * @date 2019/12/02
     */
    public interface Subject {
    
        /**
         * 注册观察者
         * 
         * @param o
         */
        public void registerObserver(Observer o); 
        
        /**
         * 去除观察者
         * 
         * @param o
         */
        public void removeObserver(Observer o);
        
        /**
         * 通知所有观察者
         */
        public void notifyObserver();
        
        
        
    }

    主题(被观察者):

    package com.study.headfirst.oberver;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 被观察者
     * 
     * @author mdl
     * @date 2019/12/02
     */
    public class WeatherData implements Subject {
    
        /**
         *记录观察者
         */
        private List<Observer> os;
    
        /**
         *温度
         */
        private float temp;
    
        /**
         *湿度
         */
        private float humidity;
    
        public WeatherData() {
            os = new ArrayList<Observer>();
        }
    
        /* (non-Javadoc)
         * @see com.study.headfirst.oberver.Subject#registerObserver(com.study.headfirst.oberver.Observer)
         */
        @Override
        public void registerObserver(Observer o) {
            os.add(o);
        }
    
        /* (non-Javadoc)
         * @see com.study.headfirst.oberver.Subject#removeObserver(com.study.headfirst.oberver.Observer)
         */
        @Override
        public void removeObserver(Observer o) {
            int i = os.indexOf(o);
            if (i > 0) {
                os.remove(i);
            }
        }
    
        /* (non-Javadoc)
         * @see com.study.headfirst.oberver.Subject#notifyObserver()
         */
        @Override
        public void notifyObserver() {
            for (Observer o : os) {
                o.update(temp, humidity);
            }
        }
    
        public void setMeasurements(float temp, float humidity) {
            this.temp = temp;
            this.humidity = humidity;
            notifyObserver();
        }
    
    }

    观察者A(当前状态布告板):

    package com.study.headfirst.oberver;
    
    /**
     * 当前观测布告:显示温度
     * 
     * @author mdl
     * @date 2019/12/02
     */
    public class CurrentConditionsDisplay implements DisplayElement, Observer{
    
        private float temp;
        
        public Subject weatherData;
        
        public CurrentConditionsDisplay(Subject weatherData) {
            this.weatherData =weatherData;
            weatherData.registerObserver(this);
        }
        
        @Override
        public void display() {
            System.out.println("当前状况-----当前温度:" +  temp);
        }
    
        /* (non-Javadoc)
         * @see com.study.headfirst.oberver.Observer#update(float)
         */
        @Override
        public void update(float temp, float humidity) {
            // TODO Auto-generated method stub
            this.temp =temp;
            display();
        }
    
    }

    观察者B(天气预报布告板):

    package com.study.headfirst.oberver;
    
    import com.study.headfirst.oberver.DisplayElement;
    import com.study.headfirst.oberver.Observer;
    
    /**
     * 天气预报:显示温度、湿度
     * 
     * @author mdl
     * @date 2019/12/09
     */
    public class ForcastDisplay implements DisplayElement, Observer{
    
        private float temp;
        
        private float humidity;
        
        public Subject weatherData;
        
        public ForcastDisplay(Subject weatherData) {
            this.weatherData =weatherData;
            weatherData.registerObserver(this);
        }
        
        @Override
        public void display() {
            System.out.println("天气预报-----当前温度:" +  temp + ", 当前湿度:" + humidity);
        }
    
        /* (non-Javadoc)
         * @see com.study.headfirst.oberver.Observer#update(float)
         */
        @Override
        public void update(float temp, float humidity) {
            // TODO Auto-generated method stub
            this.temp =temp;
            this.humidity =humidity;
            display();
        }
    
    }

    测试:

    package com.study.headfirst.oberver;
    
    /**
     * 观察者模式
     * 1. 主题的注册、移除、通知
     * 2. 观察者接受通知后的动作
     * 
     * @author mdl
     * @date 2019/12/02
     */
    public class Test {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            WeatherData subject =new WeatherData();
            CurrentConditionsDisplay ccd =new CurrentConditionsDisplay(subject);
            ForcastDisplay forcastDisplay =new ForcastDisplay(subject);
            subject.setMeasurements(27f, 80f);
            System.out.println("==================================");
            subject.setMeasurements(35f, 60f);
        }
    
    }

    每一步脚印都要扎得深一点!
  • 相关阅读:
    2020-11-15(第十一周)助教周小结
    2020-11-08(第十周)助教周小结
    2020-11-01助教周小结(第九周)
    Template.
    OO第四单元总结
    OO第三单元总结
    OO第二单元总结
    OO第一单元总结
    AFO
    Codeforces Round #424 (Div. 2)
  • 原文地址:https://www.cnblogs.com/bloodthirsty/p/12010563.html
Copyright © 2020-2023  润新知