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

    技术2025-01-20  4

    深入浅出设计模式-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);    }

    最新回复(0)