观察者模式

1.一对多的依赖关系,一变化多感知

2.代码

c++:

  1 //observer c++
  2 #include <iostream>
  3 #include <list>
  4 using namespace std;
  5 
  6 //Observer
  7 class Observer{
  8 public:
  9     virtual void update(float temp,float humidity,float pressure) = 0;
 10 };
 11 
 12 //DisplayElement
 13 class DisplayElement{
 14 public:
 15     virtual void display() = 0;
 16 };
 17 
 18 //Subject
 19 class Subject{
 20 public:
 21     virtual void registerObserver(Observer* o) = 0;
 22     virtual void removeObserver  (Observer* o) = 0;
 23     virtual void notifyObservers ()            = 0;
 24     
 25 };
 26 
 27 class WeatherData : public Subject{
 28 public:
 29     WeatherData(){}
 30     void registerObserver(Observer* o){
 31         if(o)
 32             observers.push_back(o);
 33     }
 34     void removeObserver(Observer* o){
 35         auto it = observers.begin();                   //begin()返回的类型由对象是否为const决定
 36         while(it != observers.end()){                  //只要执行了erase(it),那么it就会变得无效,
 37                                                        //那么执行it++就肯定会出错,erase 返回指向删除后位置,要写 it = erase(it);
 38             if(*it == o)
 39                 it = observers.erase(it);
 40         }
 41     }
 42     void notifyObservers(){
 43         for(Observer* obs : observers){
 44             obs->update(temperature,humidity,pressure);
 45         }
 46     }
 47     void measurementsChanged(){
 48         notifyObservers();
 49     }
 50     void setMeasurements(float temperature,float humidity,float pressure){
 51         this->temperature = temperature;
 52         this->humidity    = humidity;
 53         this->pressure    = pressure;
 54         measurementsChanged();
 55     }
 56 
 57 private:
 58     list<Observer*> observers;
 59     float temperature;
 60     float humidity;
 61     float pressure;
 62 };
 63 
 64 //Current Display
 65 class CurrentConditonDisplay : public Observer,DisplayElement{
 66 
 67 public:
 68     //抽象类型不能用作形参类型,函数返回类型
 69     CurrentConditonDisplay(WeatherData* weatherData){
 70         this->weatherData = weatherData;
 71         weatherData->registerObserver(this);
 72     }
 73     void update(float temperature,float humidity,float pressure){
 74         this->temperature = temperature;
 75         this->humidity    = humidity;
 76         display();
 77     }
 78 
 79     void display(){
 80         cout<<"\r\nCurrent condition:"<<temperature<<"F degree and "<<humidity<<"%humidity";
 81     }
 82     
 83 private:
 84     float temperature;
 85     float humidity;
 86     WeatherData* weatherData;
 87 };
 88 
 89 //
 90 int main(){
 91     WeatherData* weatherData = new WeatherData();        //WeatherData
 92     CurrentConditonDisplay* currentDisplay = new CurrentConditonDisplay(weatherData);
 93 
 94     weatherData->setMeasurements(80,65,26.3f);
 95     weatherData->setMeasurements(89,61,30.3f);
 96     
 97     //remove
 98     weatherData->removeObserver(currentDisplay);
 99     weatherData->setMeasurements(76,67,12.3f);
100 
101     return 0;
102 }

 

 java:

(1)

 1 import java.util.ArrayList;
 2 
 3 //Subject
 4 interface Subject{
 5     public void registerObserver(Observer o);
 6     public void removeObserver(Observer o);
 7     public void notifyObservers();
 8 }
 9 
10 class WeatherData implements Subject{
11     private ArrayList<Observer> observers;
12     private float temperature;
13     private float humidity;
14     private float pressure;
15     
16     public WeatherData(){
17         observers = new ArrayList<Observer>();
18     }
19     //+
20     public void registerObserver(Observer o){
21         observers.add(o);
22     }
23     //-
24     public void removeObserver(Observer o){
25         int i = observers.indexOf(o);
26         if(i >= 0)
27             observers.remove(i);
28     }
29     // )))
30     public void notifyObservers(){
31         for (Observer observer : observers){
32             observer.update(temperature,humidity,pressure);
33         }
34     }
35     public void measurementsChanged(){
36         notifyObservers();
37     }
38     public void setMeasurements(float temperature,float humidity,float pressure){
39         this.temperature = temperature;
40         this.humidity    = humidity;
41         this.pressure    = pressure;
42         measurementsChanged();
43     }
44 }
45 //Observer
46 interface Observer{
47     public void update(float temp,float humidity,float pressure);
48 }
49 
50 interface DisplayElement{
51     public void display();
52 }
53 
54 //Current Display
55 class CurrentConditonDisplay implements Observer,DisplayElement{
56     private float temperature;
57     private float humidity;
58     private Subject weatherData;                           //Subject
59     
60     public CurrentConditonDisplay(Subject weatherData){
61         this.weatherData = weatherData;
62         weatherData.registerObserver(this);
63     }
64     public void update(float temperature,float humidity,float pressure){
65         this.temperature = temperature;
66         this.humidity    = humidity;
67         display();
68     }
69 
70     public void display(){
71         System.out.println("\r\nCurrent condition:" + temperature + "F degree and " + humidity + "%humidity");
72     }
73 }
74 public class WeatherStation{
75     public static void main(String[] args){
76         WeatherData weatherData = new WeatherData();        //WeatherData
77         CurrentConditonDisplay currentDisplay = new CurrentConditonDisplay(weatherData);
78         //CurrentConditonDisplay currentDisplay2 = new CurrentConditonDisplay(weatherData);
79         
80         weatherData.setMeasurements(80,65,26.3f);
81         weatherData.setMeasurements(89,61,30.3f);
82         
83         //remove
84         weatherData.removeObserver(currentDisplay);
85         weatherData.setMeasurements(76,67,12.3f);
86     }
87 }

 

(2)用内置Observable

 1 //use java Observable
 2 //Observable is a class not interface
 3 import java.util.Observable;
 4 import java.util.Observer;
 5 
 6 class WeatherData extends Observable{
 7     private float temperature;
 8     private float humidity;
 9     private float pressure;
10     
11     public WeatherData(){}
12     public void measurementsChanged(){
13         setChanged();
14         notifyObservers();
15     }
16     public void setMeasuremants(float temperature,float humidity,float pressure){
17         this.temperature = temperature;
18         this.humidity    = humidity;
19         this.pressure    = pressure;
20         measurementsChanged();
21     }
22     public float getTempreature(){
23         return temperature;
24     }
25     public float getHumidity(){
26         return humidity;
27     }
28     public float getPressure(){
29         return pressure;
30     }
31 }
32 
33 //
34 interface DisplayElement {
35     public void display();
36 }
37 
38 class CurrentConditionDisplay implements Observer,DisplayElement{
39     Observable observable;
40     private float temperature;
41     private float humidity;
42     
43     public CurrentConditionDisplay(Observable observable){
44         this.observable = observable;
45         observable.addObserver(this);
46     }
47     @Override
48     public void update(Observable obs,Object arg){
49         if(obs instanceof WeatherData){
50             WeatherData weatherData = (WeatherData)obs;
51             this.temperature        = weatherData.getTempreature();
52             this.humidity           = weatherData.getHumidity();
53             display();
54         }
55     }
56     public void display(){
57         System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
58     }
59 }
60              
61 public class WeatherStationObable{
62     public static void main(String[] args){
63         WeatherData weatherData = new WeatherData();
64         CurrentConditionDisplay display_1 = new CurrentConditionDisplay(weatherData);
65         
66         weatherData.setMeasuremants(21,34,65);
67         weatherData.setMeasuremants(31,42,75);
68     }
69 }

 

 3.杂注:

(1) 有多个观察者时,不可依赖特定通知顺序

(2)针对接口编程,不针对实现

(3)为对象间松耦合设计而努力

(4)找出变化的方面,和不变的方面分离

    变化:主题的状态,观察者数量,类型;可以改变依赖于主题状态的对象,却不改变主题。

(5)多用组合,少用继承

    将观察者组合进主题中,对象间关系不是继承产生,在运行中组合产生。

 

posted @ 2020-04-06 21:07  三岁玩童  阅读(121)  评论(0编辑  收藏  举报