亚洲免费不卡_在线视频精品_国产尤物精品_久久久久网址_久久精品91_欧美va天堂在线_狠狠入ady亚洲精品_亚洲午夜精品福利_国产精品草草_午夜精品久久99蜜桃的功能介绍

三種觀察者模式的C#實現
來源:易賢網 閱讀:3788 次 日期:2015-04-08 14:44:58
溫馨提示:易賢網小編為您整理了“三種觀察者模式的C#實現”,方便廣大網友查閱!

說起觀察者模式,估計在園子里能搜出一堆來。所以寫這篇博客的目的有兩點:

觀察者模式是寫松耦合代碼的必備模式,重要性不言而喻,拋開代碼層面,許多組件都采用了Publish-Subscribe模式,所以我想按照自己的理解重新設計一個使用場景并把觀察者模式靈活使用在其中

我想把C#中實現觀察者模式的三個方案做一個總結,目前還沒看到這樣的總結

現在我們來假設這樣的一個場景,并利用觀察者模式實現需求:

場景:未來智能家居進入了每家每戶,每個家居都留有API供客戶進行自定義整合,所以第一個智能鬧鐘(smartClock)先登場,廠家為此鬧鐘提供了一組API,當設置一個鬧鈴時間后該鬧鐘會在此時做出通知,我們的智能牛奶加熱器,面包烘烤機,擠牙膏設備都要訂閱此鬧鐘鬧鈴消息,自動為主人準備好牛奶,面包,牙膏等。

這個場景是很典型的觀察者模式,智能鬧鐘的鬧鈴是一個主題(subject),牛奶加熱器,面包烘烤機,擠牙膏設備是觀察者(observer),觀察者只需要訂閱這個主題即可實現松耦合的編碼模型,讓我們通過三種方案逐一實現此需求。

一、利用.net的Event模型來實現

.net中的Event模型是一種典型的觀察者模型,在.net出身之后被大量應用在了代碼當中,我們看事件模型如何在此種場景下使用,

首先介紹下智能鬧鐘,廠家提供了一組很簡單的API

public void SetAlarmTime(TimeSpan timeSpan)

{

_alarmTime = _now().Add(timeSpan);

RunBackgourndRunner(_now, _alarmTime);

}

SetAlarmTime(TimeSpan timeSpan)用來定時,當用戶設置好一個時間后,鬧鐘會在后臺跑一個類似于while(true)的循環對比時間,當鬧鈴時間到了后要發出一個通知事件出來

protected void RunInBackgournd(Func<DateTime> now,DateTime? alarmTime )

{

if (alarmTime.HasValue)

{

var cancelToken = new CancellationTokenSource();

var task = new Task(() =>

{

while (!cancelToken.IsCancellationRequested)

{

if (now.AreEquals(alarmTime.Value))

{

//鬧鈴時間到了

ItIsTimeToAlarm();

cancelToken.Cancel();

}

cancelToken.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(2));

}

}, cancelToken.Token, TaskCreationOptions.LongRunning);

task.Start();

}

}

其他代碼并不重要,重點在當鬧鈴時間到了后要執行ItIsTimeToAlarm(); 我們在這里發出事件以便通知觀察者,.net中實現event模型有三要素,

1.為主題(subject)要定義一個event, public event Action<Clock, AlarmEventArgs> Alarm;

2.為主題(subject)的信息定義一個EventArgs,即AlarmEventArgs,這里面包含了事件所有的信息

3.主題(subject)通過以下方式發出事件

var args = new AlarmEventArgs(_alarmTime.Value, 0.92m);

OnAlarmEvent(args);

OnAlarmEvent方法的定義

public virtual void OnAlarm(AlarmEventArgs e)

{

if(Alarm!=null)

Alarm(this,e);

}

這里要注意命名規范,事件內容-AlarmEventArgs,事件-Alarm(動詞,例如KeyPress),觸發事件的方法 void OnAlarm(),這些命名都要符合事件模型的命名規范。

智能鬧鐘(SmartClock)已經實現完畢,我們在牛奶加熱器(MilkSchedule)中訂閱這個Alarm消息:

public void PrepareMilkInTheMorning()

{

_clock.Alarm += (clock, args) =>

{

Message =

"Prepraring milk for the owner, The time is {0}, the electric quantity is {1}%".FormatWith(

args.AlarmTime, args.ElectricQuantity*100);

Console.WriteLine(Message);

};

_clock.SetAlarmTime(TimeSpan.FromSeconds(2));

}

在面包烘烤機中同樣可以用_clock.Alarm+=(clock,args)=>{//it is time to roast bread}訂閱鬧鈴消息。

至此,event模型介紹完畢,實現過程還是有點繁瑣的,并且事件模型使用不當會有memory leak的問題,當觀察者(obsever)訂閱了一個生命周期較長的主題(該主題生命周期長于觀察者),該觀察者將不會被垃圾回收(因為還有引用指向主題),詳見Understanding and Avoiding Memory Leaks with Event Handlers and Event Aggregators,開發者需要顯示退訂該主題(-=)。

園子里老A也寫過一篇如何利用弱引用解決該問題的博客:如何解決事件導致的Memory Leak問題:Weak Event Handlers。

二、利用.net中IObservable<out T>和IObserver<in T>實現觀察者模式

IObservable<out T> 顧名思義-可觀察的事物,即主題(subject),Observer很明顯就是觀察者了。

在我們的場景中智能鬧鐘是IObservable,該接口只定義了一個方法IDisposable Subscribe(IObserver<T> observer);該方法命名讓人有點犯暈,Subscribe即訂閱的意思,不同于之前提到過的觀察者(observer)訂閱主題(subject)。在這里是主題(subject)來訂閱觀察者(observer),其實這里也說得通,因為在該模型下,主題(subject)維護了一個觀察者(observer)列表,所以有主題訂閱觀察者之說,我們來看鬧鐘的IDisposable Subscribe(IObserver<T> observer)實現:

public IDisposable Subscribe(IObserver<AlarmData> observer)

{

if (!_observers.Contains(observer))

{

_observers.Add(observer);

}

return new DisposedAction(() => _observers.Remove(observer));

}

可以看到這里維護了一個觀察者列表_observers,鬧鐘在到點了之后會遍歷所有觀察者列表將消息逐一通知給觀察者

public override void ItIsTimeToAlarm()

{

var alarm = new AlarmData(_alarmTime.Value, 0.92m);

_observers.ForEach(o=>o.OnNext(alarm));

}

很明顯,觀察者有個OnNext方法,方法簽名是一個AlarmData,代表了要通知的消息數據,接下來看看牛奶加熱器的實現,牛奶加熱器作為觀察者(observer)當然要實現IObserver接口

public  void Subscribe(TimeSpan timeSpan)

{

_unSubscriber = _clock.Subscribe(this);

_clock.SetAlarmTime(timeSpan);

}

public  void Unsubscribe()

{

_unSubscriber.Dispose();

}

public void OnNext(AlarmData value)

{

Message =

"Prepraring milk for the owner, The time is {0}, the electric quantity is {1}%".FormatWith(

value.AlarmTime, value.ElectricQuantity * 100);

Console.WriteLine(Message);

}

除此之外為了方便使用面包烘烤器,我們還加了兩個方法Subscribe()和Unsubscribe(),看調用過程

var milkSchedule = new MilkSchedule();

//Act

milkSchedule.Subscribe(TimeSpan.FromSeconds(12));

三、Action函數式方案

在介紹該方案之前我需要說明,該方案并不是一個觀察者模型,但是它卻可以實現同樣的功能,并且使用起來更加簡練,也是我最喜歡的一種用法。

這種方案中,智能鬧鐘(smartClock)提供的API需要設計成這樣:

public void SetAlarmTime(TimeSpan timeSpan,Action<AlarmData> alarmAction)

{

_alarmTime = _now().Add(timeSpan);

_alarmAction = alarmAction;

RunBackgourndRunner(_now, _alarmTime);

}

方法簽名中要接受一個Action<T>,鬧鐘在到點后直接執行該Action<T>即可:

public override void ItIsTimeToAlarm()

{

if (_alarmAction != null)

{

var alarmData = new AlarmData(_alarmTime.Value, 0.92m);

_alarmAction(alarmData);

}

}

牛奶加熱器中使用這種API也很簡單:

_clock.SetAlarmTime(TimeSpan.FromSeconds(1), (data) =>

{

Message =

"Prepraring milk for the owner, The time is {0}, the electric quantity is {1}%".FormatWith(

data.AlarmTime, data.ElectricQuantity * 100);

});

在實際使用過程中我會把這種API設計成fluent api,調用起來代碼更清晰:

智能鬧鐘(smartClock)中的API:

public Clock SetAlarmTime(TimeSpan timeSpan)

{

_alarmTime = _now().Add(timeSpan);

RunBackgourndRunner(_now, _alarmTime);

return this;

}

public void OnAlarm(Action<AlarmData> alarmAction)

{

_alarmAction = alarmAction;

}

牛奶加熱器中進行調用:

_clock.SetAlarmTime(TimeSpan.FromSeconds(2))

.OnAlarm((data) =>

{

Message =

"Prepraring milk for the owner, The time is {0}, the electric quantity is {1}%".FormatWith(

data.AlarmTime, data.ElectricQuantity * 100);

});

顯然改進后的寫法語義更好:鬧鐘.設置鬧鈴時間().當報警時(()=>{執行以下功能})

這種函數式寫法更簡練,但是也有明顯的缺點,該模型不支持多個觀察者,當面包烘烤機使用這樣的API時,會覆蓋牛奶加熱器的函數,即每次只支持一個觀察者使用。

更多信息請查看IT技術專欄

更多信息請查看技術文章
易賢網手機網站地址:三種觀察者模式的C#實現
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點

版權所有:易賢網

亚洲免费不卡_在线视频精品_国产尤物精品_久久久久网址_久久精品91_欧美va天堂在线_狠狠入ady亚洲精品_亚洲午夜精品福利_国产精品草草_午夜精品久久99蜜桃的功能介绍
欧美一级网站| 欧美视频1区| 午夜精品久久99蜜桃的功能介绍| 国产一区二区三区的电影| 国产人成精品一区二区三| 亚洲综合激情| 国产精品大片免费观看| 中日韩视频在线观看| 美日韩精品视频| 亚洲高清资源| 午夜精品一区二区三区四区| 日韩午夜免费视频| 午夜亚洲精品| 亚洲国产精品视频一区| 老司机午夜免费精品视频| 亚洲欧洲一区二区天堂久久| 午夜精品电影| 亚洲免费婷婷| 一本色道久久综合亚洲精品婷婷| 免费试看一区| 在线视频精品一区| 狠狠色伊人亚洲综合网站色| 欧美va天堂| 亚洲一区二区三区精品在线观看 | 国产精品毛片| 国产精品hd| 老司机精品视频网站| 国产欧美日本在线| 亚洲视频狠狠| 黄色精品一区| 欧美亚韩一区| 欧美精品一线| 欧美午夜在线视频| 欧美破处大片在线视频| 欧美永久精品| 久久亚洲综合| 久久久久久久欧美精品| 亚洲免费网站| 久久经典综合| 久久精品午夜| 久久午夜精品| 欧美精品一区三区在线观看| 亚洲欧美在线网| 午夜欧美精品| 国内精品一区二区| 国产综合自拍| 亚洲青色在线| 国产精品日韩高清| 午夜在线观看免费一区| 久久午夜av| 欧美日韩精品久久| 国产自产在线视频一区| 韩日成人av| 亚洲第一毛片| 亚洲一卡久久| 欧美极品一区| 亚洲精品美女91| 夜夜嗨一区二区| 国产私拍一区| 久久精品五月| 亚洲第一毛片| 噜噜噜久久亚洲精品国产品小说| 欧美 日韩 国产在线| 国产一区二区三区四区三区四| 国产一区二区三区四区hd| 亚洲一级黄色| 亚洲欧美电影在线观看| 午夜国产欧美理论在线播放| 亚洲高清视频一区| 亚洲一区二区三区欧美| 欧美阿v一级看视频| 伊人成人网在线看| 亚洲一区二区在| 欧美天天视频| 欧美中文字幕| 亚洲黄色三级| 午夜欧美理论片| 中日韩在线视频| 欧美日产一区二区三区在线观看| 18成人免费观看视频| 国产精品久久九九| 欧美午夜一区| 母乳一区在线观看| 伊人蜜桃色噜噜激情综合| 乱码第一页成人| 最新成人av网站| 欧美福利在线| 久久av一区二区三区| 黄色日韩在线| 狂野欧美一区| 午夜在线一区| 国产精品区二区三区日本| 激情欧美一区| 欧美片第1页综合| 毛片一区二区| 亚洲免费在线| 国产偷久久久精品专区| 亚洲国产第一| 在线观看亚洲视频啊啊啊啊| 欧美日韩在线精品| 欧美一区二区三区四区在线观看地址 | 黑人中文字幕一区二区三区| 午夜在线观看免费一区| 亚洲美女一区| 亚洲国产专区| 在线国产精品一区| 亚洲午夜在线| 黄色成人在线网址| 韩日午夜在线资源一区二区| 久久久亚洲人| 久久国产精品久久精品国产 | 欧美成ee人免费视频| 在线国产精品一区| 一区在线观看| 亚洲第一伊人| 亚洲精品资源| 日韩视频在线播放| 99国产一区| 国产精品视频久久一区| 国产精品免费区二区三区观看| 9久re热视频在线精品| 亚洲黄色高清| 国产九区一区在线| 久久精品免费| 欧美福利一区二区三区| 欧美区一区二| 精品91在线| 国产欧美短视频| 毛片一区二区| 午夜精品美女久久久久av福利| 午夜精品久久99蜜桃的功能介绍| 欧美精品偷拍| 亚洲国产高清一区| 国产精品呻吟| 午夜精品免费| 亚洲精选在线| 米奇777在线欧美播放| 欧美精品观看| aⅴ色国产欧美| 久久久久免费| 红桃视频欧美| 国产精品普通话对白| 欧美精品一线| 国产欧美一区二区三区国产幕精品| 香蕉久久夜色精品| 欧美日韩在线精品| 国产精品三上| 韩日视频一区| 久久国产精品亚洲va麻豆| 欧美视频网站| 久久国产高清| 亚洲看片一区| 国产精品v日韩精品v欧美精品网站| 亚洲国内在线| 久久久久免费| aa亚洲婷婷| 黄色亚洲大片免费在线观看| 久久国产精品久久久久久电车| 国产精品v欧美精品v日韩| 国产精品推荐精品| 国产精品a级| 蜜乳av另类精品一区二区| 亚洲国产美女 | 伊人成年综合电影网| 午夜亚洲影视| 一区二区三区免费看| 国产精品九九| 久久一区国产| 亚洲综合首页| 国产视频一区三区| 在线观看亚洲| 好吊一区二区三区| 午夜精品一区二区三区四区| 性欧美videos另类喷潮| 日韩亚洲视频| 日韩一区二区久久| 在线日韩av| 伊人精品成人久久综合软件| 国产精品v欧美精品v日韩精品 | 激情欧美日韩一区| 欧美国产综合| 欧美成人tv| 午夜精品av| 欧美日韩一区在线播放| 欧美激情综合| 国产精品sss| 欧美日韩国产精品一卡| 欧美日本中文| 国内精品福利| 亚洲激情婷婷| 亚洲精品乱码| 国产日韩欧美三区| 亚洲一区成人| 久久中文在线| 欧美另类专区| 在线观看不卡| 一道本一区二区| 亚洲欧美日韩国产| 久久青草久久| 欧美一区精品| 国产综合色一区二区三区| 亚洲高清激情| 国产精品一卡| 欧美一区成人| 亚洲激情啪啪| 模特精品在线| 韩日视频一区| 国产欧美日韩综合一区在线观看 | 久久国产手机看片| 欧美一区激情| 亚洲国产精品一区制服丝袜| 亚洲精品九九| 亚洲一区在线免费| 久久综合一区| 精品动漫3d一区二区三区免费| 最新成人av网站| 国产日韩欧美综合精品| 欧美1区2区| 日韩午夜免费| 欧美精品一区二区视频| 亚洲久色影视| 欧美激情第二页| 亚洲美女黄色| 欧美在线精品一区| 亚洲毛片视频| 欧美视频久久| 免费精品视频| 亚洲麻豆视频| 久久尤物视频| 一区二区三区偷拍| 欧美精品一区三区在线观看| 99国产成+人+综合+亚洲欧美| 性久久久久久| 亚洲青涩在线| 好吊日精品视频| 久久精品动漫| 一本久道久久综合婷婷鲸鱼| 久久久水蜜桃av免费网站| 99国产精品久久久久老师| 欧美精品一区二区三区在线看午夜| 一区二区三区免费看| 国内精品久久久久久久影视蜜臀| 午夜亚洲性色福利视频| 日韩亚洲视频| 噜噜爱69成人精品| 18成人免费观看视频| 久久精品女人| 99精品免费视频| 国内在线观看一区二区三区| 欧美在线高清| 久久久久se| 亚洲一区日韩在线| 国产亚洲成人一区| 国产欧美日韩在线播放| 亚洲日韩成人| 亚洲大片av| 亚洲欧洲一区二区天堂久久| 亚洲一级一区| 在线看片欧美| 在线看片一区| 亚洲人久久久| 亚洲欧洲久久| 在线视频精品一区| 国产一区二区高清视频| 亚洲美女啪啪| 国产一区二区三区的电影| 一区二区精品| 国产精品三上| 老鸭窝毛片一区二区三区| 性欧美暴力猛交另类hd| 欧美亚洲视频| 美女精品在线| 午夜欧美精品| 国内综合精品午夜久久资源| 亚洲私人影院| 亚洲视频二区| 国产精品一区二区欧美| 亚洲欧美国产精品桃花| 久久亚洲二区| 国产精品a久久久久| 亚洲国产精品综合| 国产精品嫩草99av在线| 久久激情综合| 国产综合婷婷| 中文精品一区二区三区 | 久久激情视频| 亚洲欧美综合| 亚洲欧洲在线一区| 香蕉av777xxx色综合一区| 欧美福利一区| 亚洲精品1234| 六月婷婷久久| 欧美日韩理论| 在线亚洲观看| 午夜国产精品视频免费体验区| 国语对白精品一区二区| 夜夜嗨av一区二区三区网站四季av| 国产一区二区三区久久| 欧美在线首页| 一区二区三区国产盗摄| 欧美成人一区二区在线| 日韩午夜精品| 国产精品扒开腿做爽爽爽软件| 亚洲精品偷拍| 亚洲欧美文学| 性xx色xx综合久久久xx| 亚洲性图久久| 老牛影视一区二区三区| 亚洲精品在线观看免费| 免费中文字幕日韩欧美| 狠狠色综合色区| 性色一区二区| 亚洲另类黄色| 国产精品国产一区二区| 亚洲一区二区三区欧美| 亚洲午夜电影| 欧美黄色免费| 欧美亚洲免费在线| av成人天堂| 激情久久久久久久| 久久久人人人| 国产精品久久波多野结衣| 国产精品初高中精品久久 | 久久三级视频| 尤物精品在线| 欧美日韩综合网| 欧美一区1区三区3区公司 | 亚洲精品韩国| 欧美.www| 欧美一区1区三区3区公司 | 伊人久久亚洲热| 久久一区精品| 欧美亚洲一区| 欧美亚洲免费在线| 国产精品日本| 99精品欧美一区二区三区| 韩国精品一区二区三区| 欧美日韩国产三区| 你懂的视频一区二区| 欧美一区二区视频在线 | 国产精品免费看| 夜夜嗨网站十八久久| 亚洲国产电影| 亚洲国产精品一区制服丝袜| 国产精品红桃| 亚洲激情欧美| 亚洲精品综合| 国产精品老牛| 久久欧美肥婆一二区| 久久亚洲精品伦理| 久久综合激情| 狠久久av成人天堂| 亚洲每日在线| 免费中文字幕日韩欧美| 美女精品一区| 欧美精品97| 亚洲视频一区| 国产欧美日韩综合一区在线播放| 国产亚洲激情| 久久精品人人| 韩日视频一区| 一区二区三区国产在线| 性欧美xxxx大乳国产app| 久久久一二三| 亚洲视频中文| 一区二区三区四区国产| 亚久久调教视频| 欧美一区1区三区3区公司 | 欧美亚洲三级| 欧美成人一区二区在线| 激情自拍一区| 中文精品视频一区二区在线观看| 亚洲一区日本| 欧美久久一级| 一区二区三区国产盗摄| 久久精品欧洲| 亚洲午夜精品国产| 国产精品久久久久毛片大屁完整版 | 久久xxxx精品视频| 欧美日韩亚洲一区三区| 国产日韩亚洲| 狠狠色丁香久久综合频道| 国产伦精品一区二区三区| 老牛国产精品一区的观看方式| 欧美久久综合| 国产伦精品一区二区三区四区免费 | 亚洲免费在线| 黄色成人91| 久久一日本道色综合久久| 亚洲成人在线| 欧美日本在线| 亚洲欧美日韩国产综合精品二区| 国产精品成人观看视频免费| 国产亚洲福利| 亚洲三级视频| 国模精品娜娜一二三区| 欧美一区在线看| 老鸭窝毛片一区二区三区| 日韩香蕉视频| 亚洲电影av|