日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

观察者模式 Observer

發(fā)布時間:2025/3/14 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 观察者模式 Observer 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

舉例說明該模式的應用場:

?

1.比方說有個氣象站,氣象站的功能就是會收集氣象信息,溫度、濕度、氣壓等;現(xiàn)在有3個關于天氣的布告欄,由于各地的生活環(huán)境、方式不一樣,所以顯示的數(shù)據(jù)信息也各有所異,比如:

①號布告欄顯示溫度和濕度就行???????? :溫度、濕度

②號布告欄顯示氣壓???????????????????????????? :氣壓

③號布告欄顯示氣象站的全部信息???? :溫度、濕度、氣壓

要求是氣象站一有新的氣象數(shù)據(jù)立馬更新3個布告欄,使信息同步準確,這種需求如何設計呢?

?

2.再舉個應用場景,如報社和讀者之間的關系,只要讀者訂閱了報社業(yè)務,報社就會如期給讀者送去報紙,讀者也可以根據(jù)自己的需要訂閱自己喜歡的類型信息,如訂閱財經(jīng)、軍事、政治等不同類型報紙,這種類型的業(yè)務如何設計呢? 先想想

?

分析:

ISubject? 報社接口,實現(xiàn)注冊對象、移除對象、向注冊的對象發(fā)送報紙

IObserver、IDisplay 讀者接口

?

結(jié)合代碼:

ISubject 接口

using?System;
using?System.Collections.Generic;
using?System.Linq;
using?System.Text;

namespace?ObserverMode.IDAL
{
????
///?<summary>
????
///?主題接口(相當于報社,一有數(shù)據(jù)更新及時通知訂閱者)
????
///?<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>功能:更新數(shù)據(jù),比如報社有了新數(shù)據(jù)過來,訂閱者及時更新</para>
????
///?</summary>
????public?interface?IObserver
????{
????????
///?<summary>
????????
///?更新數(shù)據(jù)
????????
///?</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>單獨有這個接口是因為不同的預訂者想呈現(xiàn)的數(shù)據(jù)是不一樣的
????
///?<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>
????????
///?構(gòu)造函數(shù)
????????
///?</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);
????????}
????}
}

?

結(jié)果:

?

?

[注]:類圖中的繼承應該是虛線,Rose掌握不熟,另外實心線帶箭頭表示,兩者有關系,如圖中ISubject箭頭指向IObject,兩者有關系,ISubject有IObject類型變量

?

轉(zhuǎn)載于:https://www.cnblogs.com/sanpi/archive/2011/07/05/2097874.html

總結(jié)

以上是生活随笔為你收集整理的观察者模式 Observer的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。