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

    观察者者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,所有的依赖者都会收到通知并及时更新。
    举一个气象观察站的例子:假如有一个气象站可以检测温度,湿度,气压,现在要把这些数据全部传送到三块显示板上,气象站是一,三块显示板是多,最容易想到的方案是定义一个气象站类WeatherData,在类里面写一个方法,把数据分别传送给三个显示板,如下所示:

    public class WeatherData {
        //实例变量声明
        public void measurementChanged() {
            //取得最近的测量值
            float temp = getTemplature();
            float humidity = getHumidity();
            float pressure = getPressure();        
            //更新显示板
            currentConditionsDisplay.update(temp, humidity, pressure);
            statisticsDisplay.update(temp, humidity, pressure);
            forecastDisplay.update(temp, humidity, pressure);
        }
    }

    上面的方式是针对的具体实现编程,所以如果要增加显示板或者减少显示板,那么上面的程序就要修改,显示板和气象站耦合在一起,这样不利于扩展。下面利用观察者模式来解决这个问题。

    //主题接口
    public interface Subject {
        public void registerObserver(Observer o);    //注册观察者
        public void removeObserver(Observer o);        //移除观察者
        public void notifyObservers();                //通知观察者
    }
    
    //观察者接口
    public interface Observer {
        public void update(float temp, float humidity, float pressure);    //更新数据
    }
    
    //显示数据接口
    public interface DisplayElement{
        public void display();
    }
    
    //气象站
    public class WeatherData implements Subject {
        private ArrayList observers;    //保存观察者的ArrayList
        private float temperature;
        private float humidity;
        private float pressure;
    
        public WeatherData() {
            observers = new ArrayList();
        }
    
        public void registerObserver(Observer o) {    //添加观察者
            observers.add(o);
        }
    
        public void removeObserver(Observer o) {    //移除观察者
            int i = observers.indexOf(o);
            if (i >= 0) {
                observers.remove(i);
            }
        }
    
        public void notifyObservers() {                //通知观察者
            for (int i = 0; i < observers.size(); i++ ) {
                Observer observer = (Observer)observers.get(i);
                observer.update(temperature, humidity, pressure);
            }
        }
    
        public void measurementChanged() {            //数据改变时通知观察者
            notifyObservers();
        }
    }
    
    //观察者
    public class CurrentConditionsDisplay implements Observer, DisplayElement {
        private float temperature;
        private float humidity;
        private Subject weatherData;    //每个观察者都有一个主题接口
    
        public CurrentConditionsDisplay (Subject weatherData) {
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }
    
        public void update(float temperature, float humidity, float pressure) {
            this.temperature = temperature;
            this.humidity = humidity;
            display();
        }
    
        public void display() {
            System.out.println("Current conditions:" + temperature + "F degrees and" + humidity + "%humidity");
        }
    }

    这样,当我们要扩展程序增加观察者时,只需写一个实现了Observer, DisplayElement接口的类就可以了,原程序不需要改动。




  • 相关阅读:
    SpringSource Tools Suite 字体偏小问题
    Ubuntu11.10 Eclipse 提示框 为黑色 解决方案
    图的广度优先搜索 皇星客栈
    哈夫曼编码 皇星客栈
    m_hWnd与this指针 皇星客栈
    建立中序线索二叉树 皇星客栈
    第一部分 整数Hash 皇星客栈
    哈夫曼树建立 皇星客栈
    Hash入门 皇星客栈
    stdin,stdout 和STDOUT_FILENO,STDIN_FILENO的学习 皇星客栈
  • 原文地址:https://www.cnblogs.com/fengz/p/6748443.html
Copyright © 2011-2022 走看看