深入浅出设计模式-002:观察者模式(Observer Pattern)

深入浅出设计模式-002:观察者模式(Observer Pattern)

一:观察者模式 = 出版者(主题Subject)+订阅者(观察者Observer)
    定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖都会收到通知并自动更新。
    主题和观察者定义了一对多关系。观察者依赖此主题,只要主题状态一有变化,观察者就会被通知。

二:松耦合的威力:当两个对象之间松耦合,他们依然可以交互,但是不太清楚彼此的细节。
    设计原则:为了交互对象之间的松耦合设计而努力。

    Subject:这是主题接口,对象使用此接口注册为观察者,或者把自己从观察者中删除。
    Observer:所有潜在的观察者必须实现观察者接口,这个接口只有UPDATE一个方法,当主题改变它时被调用。
    ConcreteSubject:实现主题接口,还用于在状态改变时更新所有当前观察者。
    ConcreteObserver:具体观察者可以是实现此接口的任意类。观察者必须注册具体主题,以便接口更新。

三:观察者定义了对象之间一对多的关系
    主题用一个共同的接口来更新观察者
    观察者和可观察者之间用松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者的接口。
    使用此模式时,你可从被观察者出推或拉数据
    有多个观察者时,不可以依赖特定的通知次序
   
四:类似于,在网上公布电话,订阅者想订阅时,可以通过电话通知。
    public interface Observer{
        //当气象观测值改变时,主题会把这些状态值当做方法的参数,传递给观察者
        void update(float tmp, float humidity, float pressure);
    }
    public interface DisplayElement{
        //当布告需要显示时,调用此方法
        void display();
    }
    public class CurrentDistionsDisplay : Observer, DisplayElement{
        private float temperature;
        private float humidity;
        private Subject weatherData;
        public CurrentDistionsDisplay(Subject weatherData){
            //注册用
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }
        public void update(float tmp, float humidity, float pressure){
            temperature = tmp;
            this.humidity = humidity;
            display();
        }
        public void display(){
            Console.WriteLine("CurrentDistionsDisplay");
        }
    }
    public class StatisticsDisplay : Observer, DisplayElement{
        private float temperature;
        private float humidity;
        private Subject weatherData;
        public StatisticsDisplay(Subject weatherData){
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }
        public void update(float tmp, float humidity, float pressure){
            temperature = tmp;
            this.humidity = humidity;
            display();
        }
        public void display(){
            Console.WriteLine("StatisticsDisplay");
        }
    }
    public class ForecastDisplay : Observer, DisplayElement{
        private float temperature;
        private float humidity;
        private Subject weatherData;
        public ForecastDisplay(Subject weatherData){
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }
        public void update(float tmp, float humidity, float pressure){
            temperature = tmp;
            this.humidity = humidity;
            display();
        }
        public void display(){
            Console.WriteLine("ForecastDisplay");
        }
    }
    public interface Subject{
        //该观察者用来注册或被删除的
        void registerObserver(Observer o);
        void removeObserver(Observer o);
        //当主题状态改变时,这个方法会被调用,以通知所有的观察者
        void notifyObservers();
    }
    public class WeatherData : Subject{
        private ArrayList observers;
        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 index = observers.IndexOf(o);
            if(index >= 0)
                observers.Remove(index);
        }
        public void notifyObservers(){
            for (int index = 0; index < observers.Count; index++){
                Observer observer = (Observer)observers[index];
                observer.update(temperature, humidity, pressure);
            }     
        }
        public void measurementsChanged(){
            notifyObservers();
        }
        public void setMeasurements(float temp, float humi, float press){
            temperature = temp;
            humidity = humi;
            pressure = press;
            measurementsChanged();
        }
    }

    static void Main(string[] args){
        WeatherData weatherData = new WeatherData();
        CurrentDistionsDisplay currentDisplay = new CurrentDistionsDisplay(weatherData);
        StatisticsDisplay statistics = new StatisticsDisplay(weatherData);
        ForecastDisplay forecast = new ForecastDisplay(weatherData);

        weatherData.setMeasurements(80, 65, 30);
        weatherData.setMeasurements(82, 70, 29);
    }

你可能感兴趣的:(深入浅出设计模式-002:观察者模式(Observer Pattern))