zoukankan      html  css  js  c++  java
  • [菜鸟的设计模式之旅]观察者模式

    [菜鸟的设计模式之旅]观察者模式

    定义:

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

    举例:

    气象站和气象展示牌,气象站捕获到的天气数据改变后,它需要及时反馈给气象展示牌,这样就能实时展示天气数据了。那么问题来了,是“气象展示牌”不停地去get气象站里的天气数据还是应该“气象站”里数据改变的时候再通知气象展示牌改变数据呢?当然是后者更合理,这就是观察者模式,气象站相当于“主题”,而气象展示牌相当于“观察者”,当然也可以加入很多其它的“观察者”,反正气象改变的时候,“主题”会通知所有的观察者。

    思路:

    “主题”接口中肯定是要有三个固定方法的,“注册观察者”,“移除观察者”“通知观察者”

    这时候有一个主题"气象站",它去实现“主题接口”,同时有一个“观察者”接口,毋庸置疑观察者都是要实现这个接口的。从uml图中可以看出,它们联系的桥梁就是相互依赖,简单的来说就是相互有对方的接口引用(把对方的接口类型作为自己某个方法的形参)

    “主题”有了观察者的引用后,将观察者作为“注册观察者”方法的形参,加入到自己的一个list集合中(存放所有的观察者),remove观察者也是同理

    而“观察者”有了“主题”的引用后,可以用主题的引用来调用主题中的注册或者移除方法,把自己(this)作为形参传进去,这样就达到了注册或者移除的目的。

    它们之间有了联系之后,沟通就方便了,主题可以调用已经注册的观察者的方法,简称“通知”,主要就是遍历刚刚说的存放所有观察者的list集合,至于什么时候遍历去调用,那就看自己的业务场景了,比如本次的气象例子,可以在气象站里的气象对应属性改变的时候,去调用气象展示板里的更新方法,这就达到了最开始我们说的气象改变,立即通知气象展示板更新数据的业务。

    代码

    具体代码可以看这里

    这里展示部分代码:这里我就粘贴了两个实现类的代码~

    package observermode.subject;
    
    import observermode.observer.Observer;
    
    import java.util.ArrayList;
    
    public class WeatherData implements Subject {
        private ArrayList<Observer> observers;
        private float temperature;
        private float humidity;
        private float pressure;
    
        public WeatherData() {
            observers = new ArrayList<Observer>();
        }
    
        @Override
        public void registerObserver(Observer o) {
                observers.add(o);
        }
    
        @Override
        public void removeObserver(Observer o) {
            int i = observers.indexOf(o);
            if (i >= 0){
                observers.remove(o);
            }
        }
    
        @Override
        public void notifyObservers() {
            for (int i = 0; i < observers.size(); i++) {
                Observer observer = observers.get(i);
                observer.update(temperature, humidity, pressure);
            }
        }
    
        public void measurementsChanged(){
            notifyObservers();
        }
    
        public void setMeasurements(float temperature,float humidity,float pressure){
            this.temperature = temperature;
            this.humidity = humidity;
            this.pressure = pressure;
            measurementsChanged();
        }
    }
    package observermode.observer;
    
    import observermode.DisplayEelment;
    import observermode.subject.Subject;
    
    public class CurrentConditionsDisplay implements Observer, DisplayEelment {
    
        private float temperature;
        private float humidity;
        private Subject weatherData;
    
        public CurrentConditionsDisplay(Subject weatherData) {
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }
    
        @Override
        public void update(float temperature, float humidity, float pressure) {
            this.temperature = temperature;
            this.humidity = humidity;
            display();
        }
    
        @Override
        public void display() {
            System.out.println("现在的温度是:" + temperature);
            System.out.println("现在的湿度是:" + humidity);
        }
    }

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

  • 相关阅读:
    XtraBackUp 热备份工具
    (原始)数据库的备份与恢复
    liunx 中安装mysql 图形界面 phpmyadmin
    mysql 引擎
    使用正则进行HTML页面属性的替换
    mysql 表锁死的问题
    mysql 函数tree状
    tree 树状构建
    java项目部署jar包
    RSA2
  • 原文地址:https://www.cnblogs.com/deepSleeping/p/10767107.html
Copyright © 2011-2022 走看看