观察者模式 Observer
舉例說明該模式的應用場景:
?
1.比方說有個氣象站,氣象站的功能就是會收集氣象信息,溫度、濕度、氣壓等;現在有3個關于天氣的布告欄,由于各地的生活環境、方式不一樣,所以顯示的數據信息也各有所異,比如:
①號布告欄顯示溫度和濕度就行???????? :溫度、濕度
②號布告欄顯示氣壓???????????????????????????? :氣壓
③號布告欄顯示氣象站的全部信息???? :溫度、濕度、氣壓
要求是氣象站一有新的氣象數據立馬更新3個布告欄,使信息同步準確,這種需求如何設計呢?
?
2.再舉個應用場景,如報社和讀者之間的關系,只要讀者訂閱了報社業務,報社就會如期給讀者送去報紙,讀者也可以根據自己的需要訂閱自己喜歡的類型信息,如訂閱財經、軍事、政治等不同類型報紙,這種類型的業務如何設計呢? 先想想
?
分析:
ISubject? 報社接口,實現注冊對象、移除對象、向注冊的對象發送報紙
IObserver、IDisplay 讀者接口
?
結合代碼:
ISubject 接口
using?System;using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
namespace?ObserverMode.IDAL
{
????///?<summary>
????///?主題接口(相當于報社,一有數據更新及時通知訂閱者)
????///?<para>包含的功能主要有:</para>
????///?<para>1.注冊對象(訂閱者)</para>
????///?<para>2.移除對象</para>
????///?<para>3.通知對象</para>
????///?</summary>
????public?interface?ISubject
????{
?????????void?RegisterObserver(IObserver?o);
?????????void?RemoveObserver(IObserver?o);
?????????void?NotifyObserver();
????}
}
?
IObserver接口
using?System;using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
namespace?ObserverMode.IDAL
{
????///?<summary>
????///?觀察者接口(訂閱者)
????///?<para>功能:更新數據,比如報社有了新數據過來,訂閱者及時更新</para>
????///?</summary>
????public?interface?IObserver
????{
????????///?<summary>
????????///?更新數據
????????///?</summary>
????????///?<param?name="temp">溫度</param>
????????///?<param?name="humidity">濕度</param>
????????///?<param?name="pressure">氣壓</param>
????????void?Update(float?temp,float?humidity,float?pressure);
????}
}
?
IDisplay接口
using?System;using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
namespace?ObserverMode.IDAL
{
????///?<summary>
????///?顯示信息接口
????///?<para>描述:剛開始有個疑問,為什么單獨需要一個顯示信息接口?</para>
????///?<para>單獨有這個接口是因為不同的預訂者想呈現的數據是不一樣的
????///?<para>不同的預訂者想看的報社新聞各有不同,關注的東西都不一樣,</para>
????///?<para>所以不同的觀察者Display都不同,因此需要這個display接口</para>
????///?</summary>
????public?interface?IdisplayElement
????{
????????void?Disyplay();
????}
}
?
?
WeatherData 類
using?System;
using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
using?System.Collections;
using?ObserverMode.IDAL;
namespace?ObserverMode
{
????///?<summary>
????///?主題類,可以理解為報社
????///?</summary>
????public?class?WeatherData?:?ISubject
????{
????????#region?變量
????????///?<summary>
????????///?觀察者集合
????????///?</summary>
????????private?ArrayList?observers;
????????///?<summary>
????????///?溫度
????????///?</summary>
????????private?float?temperature;
????????///?<summary>
????????///?濕度
????????///?</summary>
????????private?float?humidity;
????????///?<summary>
????????///?氣壓
????????///?</summary>
????????private?float?pressure;
????????#endregion
????????
????????///?<summary>
????????///?構造函數
????????///?</summary>
????????public?WeatherData()
????????{
????????????observers?=?new?ArrayList();
????????}
????????#region?ISubject?成員
????????///?<summary>
????????///?添加觀察者
????????///?</summary>
????????///?<param?name="o">預訂者</param>
????????public?void?RegisterObserver(IObserver?o)
????????{
????????????observers.Add(o);
????????}
????????///?<summary>
????????///?移除觀察者
????????///?</summary>
????????///?<param?name="o"></param>
????????public?void?RemoveObserver(IObserver?o)
????????{
????????????#region?Java
????????????//int?i?=?observers.IndexOf(o);
????????????//if?(i?>=?0)
????????????//{
????????????//????observers.Remove(i);
????????????//}
????????????#endregion???????????
????????????//C#
????????????if?(observers.Contains(o))
????????????{
????????????????observers.Remove(o);
????????????}
????????}
????????///?<summary>
????????///?通知觀察者
????????///?</summary>
????????public?void?NotifyObserver()
????????{
????????????for?(int?i?=?0;?i?<?observers.Count;?i++)
????????????{
????????????????IObserver?observer?=?(IObserver)observers[i];
????????????????observer.Update(temperature,?humidity,?pressure);
????????????}
????????}
????????///?<summary>
????????///?當報社得到最新消息時,我們就通知觀察者
????????///?</summary>
????????public?void?MeasurementsChanged()
????????{
????????????NotifyObserver();
????????}
????????///?<summary>
????????///?設置值,并告知預訂者
????????///?</summary>
????????///?<param?name="temperature"></param>
????????///?<param?name="humidity"></param>
????????///?<param?name="pressure"></param>
????????public?void?SetMessurement(float?temperature,?float?humidity,?float?pressure)
????????{
????????????this.temperature?=?temperature;
????????????this.humidity?=?humidity;
????????????this.pressure?=?pressure;
????????????MeasurementsChanged();
????????}
????????#endregion
????}
}
?
①號布告欄
using?System;using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
using?ObserverMode.IDAL;
namespace?ObserverMode
{
????///?<summary>
????///?預訂者A
????///?</summary>
????public?class?UserA:IObserver,IdisplayElement
????{
????????private?float?temperature;
????????private?float?humidity;
????????private?ISubject?weatherData;
????????public?UserA(ISubject?weatherData)
????????{
????????????this.weatherData?=?weatherData;
????????????weatherData.RegisterObserver(this);
????????}
????????#region?IObserver?成員
????????public?void?Update(float?temp,?float?humidity,?float?pressure)
????????{
????????????this.temperature?=?temp;
????????????this.humidity?=?humidity;
????????????Disyplay();
????????}
????????#endregion
????????#region?IdisplayElement?成員
????????public?void?Disyplay()
????????{
????????????Console.WriteLine("我是用戶A,我只關心溫度和濕度情況,當前溫度為:"+temperature+"?濕度為:"+humidity);
????????}
????????#endregion
????}
}
?
②號布告欄
using?System;using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
using?ObserverMode.IDAL;
namespace?ObserverMode
{
????public?class?UserB:IObserver,IdisplayElement
????{
????????private?float?pressure;
????????private?ISubject?subject;
????????public?UserB(ISubject?subject)
????????{
????????????this.subject?=?subject;
????????????subject.RegisterObserver(this);
????????}
????????#region?IdisplayElement?成員
????????public?void?Disyplay()
????????{
????????????Console.WriteLine("我是用戶B,我只對氣壓感興趣,當前氣壓值為:"+pressure);
????????}
????????#endregion
????????#region?IObserver?成員
????????public?void?Update(float?temp,?float?humidity,?float?pressure)
????????{
????????????this.pressure?=?pressure;
????????????Disyplay();
????????}
????????#endregion
????}
}
?
Main()
using?System;using?System.Collections.Generic;
using?System.Linq;
using?System.Text;
namespace?ObserverMode
{
????class?Program
????{
????????static?void?Main(string[]?args)
????????{
????????????WeatherData?weatherData?=?new?WeatherData();
????????????UserA?userA?=?new?UserA(weatherData);
????????????UserB?userB?=?new?UserB(weatherData);
????????????//weatherData.RemoveObserver(userB);?????????
????????????weatherData.SetMessurement(11,?22,?33);
????????????weatherData.SetMessurement(111,?222,?333);
????????????weatherData.SetMessurement(1111,?2222,?3333);
????????}
????}
}
?
結果:
?
?
[注]:類圖中的繼承應該是虛線,Rose掌握不熟,另外實心線帶箭頭表示,兩者有關系,如圖中ISubject箭頭指向IObject,兩者有關系,ISubject有IObject類型變量
?
轉載于:https://www.cnblogs.com/sanpi/archive/2011/07/05/2097874.html
總結
以上是生活随笔為你收集整理的观察者模式 Observer的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Response.ContentType
- 下一篇: 用js实现统计字符串里面的出现次数最多的