日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
解析.NET觀察者模式(ObserverPattern)

概要

我們提供的服務(wù)有:成都網(wǎng)站制作、成都做網(wǎng)站、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、高州ssl等。為上千余家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的高州網(wǎng)站制作公司

觀察者模式是一種設(shè)計(jì)模式。設(shè)計(jì)模式是面向?qū)ο笏枷氲募蟪桑珿OF在其經(jīng)典著作中總結(jié)了23種設(shè)計(jì)模式,又可分為:創(chuàng)建型、結(jié)構(gòu)型和行為型3個(gè)大類,其中觀察者模式屬于行為型模式。

目錄 

觀察者模式定義

實(shí)現(xiàn)觀察者模式的過(guò)程

觀察者模式結(jié)構(gòu)

觀察者模式實(shí)例

觀察者模式總結(jié)

一、觀察者模式定義

1.觀察者模式定義了對(duì)象間的一對(duì)多依賴關(guān)系。當(dāng)一方的對(duì)象改變狀態(tài)時(shí),所有的依賴者都會(huì)被通知并自動(dòng)被更新。

2.在觀察者模式中,被依賴的一方叫做目標(biāo)或主題(Subject),依賴方叫做觀察者(Observers)。

二、實(shí)現(xiàn)觀察者模式的過(guò)程  

實(shí)現(xiàn)觀察者模式有很多形式,比較直觀的是使用一種“注冊(cè)--通知--撤銷注冊(cè)”的形式。下面的三個(gè)圖詳細(xì)的描述了這樣一種過(guò)程:

1.觀察者

(Observer)將自己注冊(cè)到被觀察對(duì)象(Subject)中,被觀察對(duì)象將觀察者存放在一個(gè)容器(Container)里。

圖一

2.被觀察對(duì)象

被觀察對(duì)象發(fā)生了某種變化(如圖中的SomeChange),從容器中得到所有注冊(cè)過(guò)的觀察者,將變化通知觀察者。

圖二

3.撤銷觀察

觀察者告訴被觀察者要撤銷觀察,被觀察者從容器中將觀察者去除。

圖三

觀察者將自己注冊(cè)到被觀察者的容器中時(shí),被觀察者不應(yīng)該過(guò)問(wèn)觀察者的具體類型,而是應(yīng)該使用觀察者的接口。這樣的優(yōu)點(diǎn)是:假定程序中還有別的觀察者,那么只要這個(gè)觀察者也是相同的接口實(shí)現(xiàn)即可。一個(gè)被觀察者可以對(duì)應(yīng)多個(gè)觀察者,當(dāng)被觀察者發(fā)生變化的時(shí)候,他可以將消息一一通知給所有的觀察者。基于接口,而不是具體的實(shí)現(xiàn)——這一點(diǎn)為程序提供了更大的靈活性。

#p#

三、觀察者模式結(jié)構(gòu)

觀察者模式是對(duì)象的行為型模式,又叫做發(fā)表-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-收聽(tīng)者(Source/Listener)模式或從屬者(Dependents)模式。觀察者模式結(jié)構(gòu)類圖如下:

圖四

1.Subject(主題接口)  

1.1規(guī)定ConcreteSubject的統(tǒng)一接口;

1.2每個(gè)Subject可以有多個(gè)Observer;

2.ConcreteSubject(具體主題)

2.1維護(hù)對(duì)所有具體觀察者的引用的列表;

2.2狀態(tài)發(fā)生變化時(shí)會(huì)發(fā)送通知給所有注冊(cè)的觀察者。

3.Observer(觀察者接口)

3.1規(guī)定ConcreteObserver的統(tǒng)一接口;

3.2定義了一個(gè)update()方法,在被觀察對(duì)象狀態(tài)改變時(shí)會(huì)被調(diào)用。

4.ConcreteObserver(具體觀察者)

4.1維護(hù)一個(gè)對(duì)ConcreteSubject的引用;

4.2特定狀態(tài)與ConcreteSubject同步;

4.3實(shí)現(xiàn)Observer接口,通過(guò)update()方法接收ConcreteSubject的通知。

四、觀察者模式實(shí)例

在之前,Bohan向我們分享了一個(gè)關(guān)于開(kāi)發(fā)下一代基于因特網(wǎng)的天氣監(jiān)測(cè)系統(tǒng)的實(shí)例。該監(jiān)測(cè)系統(tǒng)涉及到的參數(shù)一共有三種:temperature, humidity, pressure,外界接受到的信息也以三種布告板顯示:currentConditionDisplay會(huì)列出當(dāng)前的氣溫,濕度和氣壓;statisticsDisplay會(huì)列出當(dāng)前的溫度最高,最低和平均值;forecastDisplay列出將來(lái)預(yù)測(cè)的天氣狀況。

1.普通實(shí)現(xiàn)方法

現(xiàn)在我們用最容易想到的一個(gè)方法來(lái)實(shí)現(xiàn)系統(tǒng):

 
 
 
 
  1. 天氣檢測(cè)系統(tǒng)普通做法  
  2.  Public  class WeatherData {  
  3.  //聲明實(shí)例變量…   
  4.  Public void measurementsChanged(){  
  5.      float temp=getTemperature();  
  6.      float humidity = getHumidity();  
  7.      float pressure=getPressure();  
  8.     currentConditionDisplay.update(temp,humidity,pressure);  
  9.      statisticsDisplay.update(temp,humidity,pressure);  
  10.      forecastDisplay.update(temp,humidity,pressure);  
  11.              }  
  12.  } 

的確,該方法可以實(shí)現(xiàn)這個(gè)系統(tǒng),但是仔細(xì)想想面向?qū)ο蟮脑O(shè)計(jì)原則就知道這種實(shí)現(xiàn)是有問(wèn)題的:

 
 
 
 
  1. currentConditionDisplay.update(temp,humidity,pressure);  
  2. statisticsDisplay.update(temp,humidity,pressure);  
  3. forecastDisplay.update(temp,humidity,pressure); 

這里違背了“面向接口編程,而不要面向?qū)崿F(xiàn)編程”的原則,會(huì)使我們?cè)谠黾踊騽h除不同的布告板時(shí)必須修改程序。也就是說(shuō),布告板相關(guān)的部分是系統(tǒng)中最不穩(wěn)定的部分,應(yīng)該將其單獨(dú)隔離開(kāi)。針對(duì)這個(gè)問(wèn)題,我們可以想到曾經(jīng)學(xué)過(guò)的另一個(gè)原則:“找到系統(tǒng)中變化的部分,將變化的部分同其它穩(wěn)定的部分隔開(kāi)”。因此,我們將使用觀察者模式來(lái)實(shí)現(xiàn)該天氣監(jiān)測(cè)系統(tǒng)。

2.觀察者模式實(shí)現(xiàn)方法

就天氣監(jiān)測(cè)系統(tǒng)問(wèn)題的應(yīng)用場(chǎng)景來(lái)說(shuō),WeatherData可以作為ConcreteSubject(具體主題)來(lái)看待,而不同的布告板(currentConditionDisplay、statisticsDisplay、forecastDisplay)則可以作為ConcreteObserver(具體觀察者)來(lái)看待,也就是說(shuō)布告板觀察WeatherData對(duì)象,如果WeatherData對(duì)象有任何狀態(tài)變化,則立刻更新布告板的數(shù)據(jù)信息。 下面是詳細(xì)的代碼實(shí)現(xiàn):

2.1主題接口ISubject.cs:

 
 
 
 
  1. public interface ISubject  
  2.       {  
  3.           void RegisterObserver(IObserver o);  
  4.          void RemoveObserver(IObserver o);  
  5.           void NotifyObserver();  
  6.       } 

2.2觀察者接口IObserver.cs:

 
 
 
 
  1. public interface IObserver  
  2.      {       //給update()方法定義了三個(gè)對(duì)應(yīng)不同氣象數(shù)據(jù)的參數(shù)。  
  3.           void Update(float temperature, float humidity, float pressure);  
  4.       } 

2.3用于顯示結(jié)果的接口IDisplayElement.cs:

 
 
 
 
  1. public interface IDisplayElement  
  2.       {  
  3.          void  Display();  
  4.        } 

2.4具體主題WeatherData.cs:

這個(gè)類是ISubject的具體實(shí)現(xiàn),內(nèi)部使用ArrayList來(lái)記錄所有注冊(cè)的觀察者,SetMeasurements() 方法是用來(lái)模擬在天氣狀況改變的時(shí)候自動(dòng)觸發(fā)MeasurementsChanged()方法的機(jī)制。

 
 
 
 
  1. 具體主題WeatherData  
  2.  public class WeatherData : ISubject  
  3.       {  
  4.           private ArrayList observers;  
  5.           private float temperature;  
  6.           private float humidity;  
  7.           private float pressure;  
  8.    
  9.          public WeatherData()  
  10.          {  
  11.              observers = new ArrayList();  
  12.          }  
  13.        #region  ISubject Members    
  14.             //注冊(cè)觀察者  
  15.          public void RegisterObserver(IObserver o)  
  16.          {  
  17.              observers.Add(o);  
  18.          }  
  19.           //移除觀察者  
  20.          public void RemoveObserver(IObserver o)  
  21.          {  
  22.              int i = observers.IndexOf(o);  
  23.              if(i >= 0)  
  24.              {  
  25.                  observers.Remove(o);  
  26.              }  
  27.          }  
  28.           //通知所有觀察者  
  29.          public void NotifyObserver()  
  30.          {  
  31.              foreach(IObserver observer in observers)  
  32.              {  
  33.                  observer.Update(temperature,humidity,pressure);  
  34.              }  
  35.          }  
  36.        #endregion  
  37.          public void MeasurementsChanged()  
  38.          {       //更新數(shù)據(jù)  
  39.              NotifyObserver();  
  40.          }  
  41.          public void SetMeasurements(float temperature, float humidity,float pressure)  
  42.          {  
  43.              this.temperature = temperature;  
  44.              this.humidity = humidity;  
  45.              this.pressure = pressure;  
  46.              MeasurementsChanged();  
  47.          }  
  48.      } 

#p#

2.5具體觀察者:

  • CurrentConditionsDisplay.cs:

這個(gè)類是IObserver和IDisplayElement的具體實(shí)現(xiàn),代表顯示當(dāng)前天氣狀況的具體布告板對(duì)象,其內(nèi)部維護(hù)了一個(gè)ISubject類型的變量,該變量在CurrentConditionsDisplay的構(gòu)造函數(shù)中被初始化,同時(shí)調(diào)用ISubject.registerObserver()方法,實(shí)現(xiàn)訂閱ISubject。

 
 
 
 
  1. CurrentConditionsDisplay   
  2.  public class CurrentConditionsDisplay :IObserver, IDisplayElement  
  3.        {  
  4.            private float temperature;  
  5.            private float humidity;  
  6.            private float pressure;  
  7.           private ISubject weatherData;  
  8.     
  9.           public CurrentConditionsDisplay(ISubject weatherData)  
  10.           {  
  11.               this.weatherData = weatherData;  
  12.               weatherData.RegisterObserver(this);  
  13.           }  
  14.        #region IObserver Members  
  15.       public void Update(float temperature, float humidity, float pressure)  
  16.           {  
  17.                //獲取更新的溫度數(shù)據(jù)  
  18.                //獲取更新的濕度數(shù)據(jù)  
  19.                //獲得更新的氣壓數(shù)據(jù)  
  20.               this.temperature = temperature;  
  21.               this.humidity = humidity;  
  22.               this.pressure = pressure;  
  23.              Display();  
  24.          }  
  25.           #endregion  
  26.      #region IDisplayElement Members  
  27.        public void Display()   //顯示當(dāng)前觀測(cè)值  
  28.           {  
  29.               Console.WriteLine( "Current conditions: " + temperature +"F degrees and " + humidity + "% humidity and "+pressure+"f pressure");  
  30.           }  
  31.           #endregion  
  32.       } 
  • ForcastDisplay.cs:
 
 
 
 
  1. ForcastDisplay   
  2.   public class ForcastDisplay : IObserver, IDisplayElement  
  3.      {   //顯示預(yù)測(cè)的天氣預(yù)報(bào)的觀察者  
  4.          private float currentPressure = 30.2f;  
  5.          private float lastPressure;  
  6.          private ISubject weatherData;  
  7.    
  8.          public ForcastDisplay(ISubject weatherData)  
  9.          {  
  10.              this.weatherData = weatherData;  
  11.              weatherData.RegisterObserver(this);  
  12.          }  
  13.          #region IObserver Members  
  14.          // 獲取更新的氣壓數(shù)據(jù)  
  15.          public void Update(float temperature, float humidity, float pressure)  
  16.          {  
  17.              lastPressure = currentPressure;  
  18.              currentPressure = pressure;  
  19.              Display();  
  20.          }  
  21.          #endregion  
  22.          #region IDisplayElement Members  
  23.           //顯示預(yù)測(cè)的天氣預(yù)報(bào)  
  24.          public void Display()        
  25.          {  
  26.              StringBuilder sb = new StringBuilder();  
  27.              sb.Append("Forecast: ");  
  28.    
  29.              if (currentPressure > lastPressure)  
  30.              {  
  31.                  sb.Append("Improving weather on the way!");  
  32.              }  
  33.              else if (currentPressure == lastPressure)  
  34.              {  
  35.                  sb.Append("More of the same");  
  36.              }  
  37.              else if (currentPressure < lastPressure)  
  38.              {  
  39.                  sb.Append("Watch out for cooler, rainy weather");  
  40.              }  
  41.              Console.WriteLine(sb.ToString());  
  42.          }  
  43.          #endregion  
  44.      } 
  • StatisticsDisplay.cs:
 
 
 
 
  1. StatisticsDisplay  
  2.     public class StatisticsDisplay : IObserver, IDisplayElement  
  3.        {  
  4.              //顯示平均、最大、最小觀測(cè)值的觀察者  
  5.         //F為華氏溫度,攝氏=5/9(F-32)  
  6.             #region Members  
  7.            private float maxTemp = 0.0f;  
  8.           private float minTemp = 200;                                      
  9.           private float temperatureSum = 0.0f;  
  10.           private int numReadings = 0;  
  11.           private ISubject weatherData;  
  12.           #endregion//Members  
  13.          #region NumberOfReadings Property  
  14.             public int NumberOfReadings  
  15.           {  
  16.               get 
  17.               {  
  18.                   return numReadings;  
  19.                }  
  20.           }  
  21.           #endregion//NumberOfReadings Property  
  22.           #region Constructor  
  23.           public StatisticsDisplay(ISubject weatherData)  
  24.           {  
  25.               this.weatherData = weatherData;  
  26.               weatherData.RegisterObserver(this);  
  27.           }  
  28.           #endregion///Constructor  
  29.          #region IObserver Members  
  30.       //獲取更新的溫度數(shù)據(jù)  
  31.           public void Update(float temperature, float humidity, float pressure)  
  32.           {  
  33.               temperatureSum += temperature;  
  34.               numReadings++;  
  35.               if (temperature > maxTemp)   
  36.               {  
  37.                   maxTemp = temperature;  
  38.               }  
  39.               if (temperature < minTemp)   
  40.               {  
  41.                   minTemp = temperature;  
  42.               }  
  43.               Display();    
  44.           }  
  45.           #endregion   
  46.          #region IDisplayElement Members   
  47.            public void Display()  
  48.           {  
  49.               Console.WriteLine("Avg/Max/Min temperature = " +(temperatureSum / numReadings)+ "F/" + maxTemp + "F/" + minTemp + "F");  
  50.           }  
  51.           #endregion   
  52.  } 

#p#

2.6主類實(shí)現(xiàn)Program.cs:

 
 
 
 
  1. 主類實(shí)現(xiàn)  
  2.  public class program  
  3.      {//實(shí)現(xiàn)天氣監(jiān)測(cè)系統(tǒng)的主類  
  4.          public static void Main(String[] args)  
  5.          {  
  6.              WeatherData weatherData = new WeatherData();  
  7.              ForcastDisplay forecastDisplay = new ForcastDisplay(weatherData);  
  8.              StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);  
  9.              CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);  
  10.              weatherData.SetMeasurements(84, 66, 31.6f);  
  11.              weatherData.SetMeasurements(88, 72, 30.0f);  
  12.              weatherData.SetMeasurements(86, 85, 30.0f);  
  13.          }  
  14.      } 

2.7運(yùn)行后結(jié)果如下:

 
 
 
 
  1. Forecast: Improving weather on the way!  
  2.  
  3. Avg/Max/Min temperature = 84F/84F/84F  
  4.  
  5. Current conditions: 84F degrees and 66% humidity and 31.6f pressure  
  6.  
  7. Forecast: Watch out for cooler, rainy weather  
  8.  
  9. Avg/Max/Min temperature = 86F/88F/84F  
  10.  
  11. Current conditions: 88F degrees and 72% humidity and 30f pressure  
  12.  
  13. Forecast: More of the same  
  14.  
  15. Avg/Max/Min temperature = 86F/88F/84F  
  16.  
  17. Current conditions: 86F degrees and 85% humidity and 30f pressure 

五、觀察者模式總結(jié)

1.觀察者模式有以下的優(yōu)點(diǎn):

1.1觀察者模式在被觀察者和觀察者之間建立一個(gè)抽象的耦合。被觀察者角色所知道的只是一個(gè)具體觀察者列表,每一個(gè)具體觀察者都符合一個(gè)抽象觀察者的接口。被觀察者并不認(rèn)識(shí)任何一個(gè)具體觀察者,它只知道它們都有一個(gè)共同的接口。

由于被觀察者和觀察者沒(méi)有緊密地耦合在一起,因此它們可以屬于不同的抽象化層次。如果被觀察者和觀察者都被扔到一起,那么這個(gè)對(duì)象必然跨越抽象化和具體化層次。

1.2觀察者模式支持廣播通訊,被觀察者會(huì)向所有的登記過(guò)的觀察者發(fā)出通知。

1.3通過(guò)Observer模式,把一對(duì)多對(duì)象之間的通知依賴關(guān)系的變得更為松散,大大地提高了程序的可維護(hù)性和可擴(kuò)展性,也很好的符合了開(kāi)放-封閉原則。

2.觀察者模式有下面的缺點(diǎn):

2.1如果一個(gè)被觀察者對(duì)象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會(huì)花費(fèi)很多時(shí)間。

2.2如果在被觀察者之間有循環(huán)依賴的話,被觀察者會(huì)觸發(fā)它們之間進(jìn)行循環(huán)調(diào)用,導(dǎo)致系統(tǒng)崩潰。在使用觀察者模式時(shí)要特別注意這一點(diǎn)。

2.3如果對(duì)觀察者的通知是通過(guò)另外的線程進(jìn)行異步投遞的話,系統(tǒng)必須保證投遞是以自恰的方式進(jìn)行的。

2.4雖然觀察者模式可以隨時(shí)使觀察者知道所觀察的對(duì)象發(fā)生了變化,但是觀察者模式?jīng)]有相應(yīng)的機(jī)制使觀察者知道所觀察的對(duì)象是怎么發(fā)生變化的。

3.觀察者模式的適用性:

3.1當(dāng)一個(gè)抽象模型有兩個(gè)方面, 其中一個(gè)方面依賴于另一方面。將這二者封裝在獨(dú)立的對(duì)象中以使它們可以各自獨(dú)立地改變和復(fù)用。

3.2當(dāng)一個(gè)對(duì)象的改變需要同時(shí)改變其它對(duì)象, 而不知道具體有多少對(duì)象有待改變。

3.3當(dāng)一個(gè)對(duì)象必須通知其它對(duì)象,而它又不能假定其它對(duì)象是誰(shuí)。換言之, 你不希望這些對(duì)象是緊密耦合的。  

源碼下載:天氣監(jiān)測(cè)系統(tǒng)的源碼 Weather


網(wǎng)站題目:解析.NET觀察者模式(ObserverPattern)
網(wǎng)址分享:http://www.dlmjj.cn/article/codeegg.html