最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

.Net行為型設計模式之觀察者模式(Observer)

 更新時間:2022年05月26日 09:40:20   作者:springsnow  
這篇文章介紹了.Net行為型設計模式之觀察者模式(Observer),文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一、動機(Motivate)

“觀察者模式”在現(xiàn)實生活中,實例其實是很多的,比如:八九十年代我們訂閱的報紙,我們會定期收到報紙,因為我們訂閱了。銀行可以給儲戶發(fā)手機短信,也是“觀察者模式”很好的使用的例子,因為我們訂閱了銀行的短信業(yè)務,當我們賬戶余額發(fā)生變化就會收到通知等。

在軟件構(gòu)建過程中,我們需要為某些對象建立一種“通知依賴關系”——一個對象(目標對象)的狀態(tài)發(fā)生改變,所有的依賴對象(觀察者對象)都將得到通知。如果這樣的依賴關系過于緊密,將使軟件不能很好地抵御變化。
使用面向?qū)ο蠹夹g,可以將這種依賴關系弱化,并形成一種穩(wěn)定的依賴關系。從而實現(xiàn)軟件體系結(jié)構(gòu)的松耦合。

二、意圖(Intent)

定義對象間的一種一對多的依賴關系,以便當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并自動更新。                                 ——《設計模式》GoF

三、結(jié)構(gòu)圖

四、模式的組成

可以看出,在觀察者模式的結(jié)構(gòu)圖有以下角色:
(1)、抽象主題角色(Subject):抽象主題把所有觀察者對象的引用保存在一個列表中,并提供增加和刪除觀察者對象的操作,抽象主題角色又叫做抽象被觀察者角色,一般由抽象類或接口實現(xiàn)。
(2)、抽象觀察者角色(Observer):為所有具體觀察者定義一個接口,在得到主題通知時更新自己,一般由抽象類或接口實現(xiàn)。
(3)、具體主題角色(ConcreteSubject):實現(xiàn)抽象主題接口,具體主題角色又叫做具體被觀察者角色。
(4)、具體觀察者角色(ConcreteObserver):實現(xiàn)抽象觀察者角色所要求的接口,以便使自身狀態(tài)與主題的狀態(tài)相協(xié)調(diào)。

五、觀察者模式的代碼實現(xiàn)

觀察者模式在顯示生活中也有類似的例子,比如:我們訂閱銀行短信業(yè)務,當我們賬戶發(fā)生改變,我們就會收到相應的短信。類似的還有微信訂閱號,今天我們就以銀行給我發(fā)送短信當我們賬戶余額發(fā)生變化的時候為例來講講觀察者模式的實現(xiàn),很簡單,現(xiàn)實生活正例子也很多,理解起來也很容易。

// 客戶端(Client)
static void Main(string[] args)
{
    //我們有了三位儲戶,都是武林高手,也比較有錢
    Depositor huangFeiHong = new BeiJingDepositor("黃飛鴻", 3000);
    Depositor fangShiYu = new BeiJingDepositor("方世玉", 1300);
    Depositor hongXiGuan = new BeiJingDepositor("洪熙官", 2500);

    BankMessageSystem beijingBank = new BeiJingBankMessageSystem();
    //這三位開始訂閱銀行短信業(yè)務
    beijingBank.Add(huangFeiHong);
    beijingBank.Add(fangShiYu);
    beijingBank.Add(hongXiGuan);

    //黃飛鴻取100塊錢
    huangFeiHong.GetMoney(100);
    beijingBank.Notify();

    //黃飛鴻和方世玉都取了錢
    huangFeiHong.GetMoney(200);
    fangShiYu.GetMoney(200);
    beijingBank.Notify();

    //他們?nèi)齻€都取了錢
    huangFeiHong.GetMoney(320);
    fangShiYu.GetMoney(4330);
    hongXiGuan.GetMoney(332);
    beijingBank.Notify();
}

//銀行短信系統(tǒng)抽象接口,是被觀察者--該類型相當于抽象主體角色Subject
public abstract class BankMessageSystem
{
    protected IList<Depositor> observers;

    //構(gòu)造函數(shù)初始化觀察者列表實例
    protected BankMessageSystem()
    {
        observers = new List<Depositor>();
    }

    //增加預約儲戶
    public abstract void Add(Depositor depositor);

    //刪除預約儲戶
    public abstract void Delete(Depositor depositor);

    //通知儲戶
    public void Notify()
    {
        foreach (Depositor depositor in observers)
        {
            if (depositor.AccountIsChanged)
            {
                depositor.Update(depositor.Balance, depositor.OperationDateTime);
                //賬戶發(fā)生了變化,并且通知了,儲戶的賬戶就認為沒有變化
                depositor.AccountIsChanged = false;
            }
        }
    }
}

//北京銀行短信系統(tǒng),是被觀察者--該類型相當于具體主體角色ConcreteSubject
public sealed class BeiJingBankMessageSystem : BankMessageSystem
{
    //增加預約儲戶
    public override void Add(Depositor depositor)
    {
        //應該先判斷該用戶是否存在,存在不操作,不存在則增加到儲戶列表中,這里簡化了
        observers.Add(depositor);
    }

    //刪除預約儲戶
    public override void Delete(Depositor depositor)
    {
        //應該先判斷該用戶是否存在,存在則刪除,不存在無操作,這里簡化了
        observers.Remove(depositor);
    }
}

//儲戶的抽象接口--相當于抽象觀察者角色(Observer)
public abstract class Depositor
{
    //狀態(tài)數(shù)據(jù)
    private string _name;
    private int _balance;
    private int _total;
    private bool _isChanged;

    //初始化狀態(tài)數(shù)據(jù)
    protected Depositor(string name, int total)
    {
        this._name = name;
        this._balance = total;//存款總額等于余額
        this._isChanged = false;//賬戶未發(fā)生變化
    }

    //儲戶的名稱,假設可以唯一區(qū)別的
    public string Name
    {
        get { return _name; }
        private set { this._name = value; }
    }

    public int Balance
    {
        get { return this._balance; }
    }

    //取錢
    public void GetMoney(int num)
    {
        if (num <= this._balance && num > 0)
        {
            this._balance = this._balance - num;
            this._isChanged = true;
            OperationDateTime = DateTime.Now;
        }
    }

    //賬戶操作時間
    public DateTime OperationDateTime { get; set; }

    //賬戶是否發(fā)生變化
    public bool AccountIsChanged
    {
        get { return this._isChanged; }
        set { this._isChanged = value; }
    }

    //更新儲戶狀態(tài)
    public abstract void Update(int currentBalance, DateTime dateTime);
}

//北京的具體儲戶--相當于具體觀察者角色ConcreteObserver
public sealed class BeiJingDepositor : Depositor
{
    public BeiJingDepositor(string name, int total) : base(name, total) { }

    public override void Update(int currentBalance, DateTime dateTime)
    {
        Console.WriteLine(Name + ":賬戶發(fā)生了變化,變化時間是" + dateTime.ToString() + ",當前余額是" + currentBalance.ToString());
    }
}

觀察者模式有些麻煩的地方就是關于狀態(tài)的處理,我這里面涉及了一些狀態(tài)的處理,大家可以細細體會一下,模式還是要多多練習,多多寫,里面的道理就不難理解了。

六、觀察者模式的實現(xiàn)要點:

使用面向?qū)ο蟮某橄?,Observer模式使得我們可以獨立地改變目標與觀察者(面向?qū)ο笾械母淖儾皇侵父拇a,而是指擴展、子類化、實現(xiàn)接口),從而使二者之間的依賴關系達致松耦合。
目標發(fā)送通知時,無需指定觀察者,通知(可以攜帶通知信息作為參數(shù))會自動傳播。觀察者自己決定是否需要訂閱通知,目標對象對此一無所知。
在C#的event中,委托充當了抽象的Observer接口,而提供事件的對象充當了目標對象。委托是比抽象Observer接口更為松耦合的設計。

1、觀察者模式的優(yōu)點:

(1)、觀察者模式實現(xiàn)了表示層和數(shù)據(jù)邏輯層的分離,并定義了穩(wěn)定的更新消息傳遞機制,并抽象了更新接口,使得可以有各種各樣不同的表示層,即觀察者。
(2)、觀察者模式在被觀察者和觀察者之間建立了一個抽象的耦合,被觀察者并不知道任何一個具體的觀察者,只是保存著抽象觀察者的列表,每個具體觀察者都符合一個抽象觀察者的接口。
(3)、觀察者模式支持廣播通信。被觀察者會向所有的注冊過的觀察者發(fā)出通知。

2、觀察者模式的缺點:

(1)、如果一個被觀察者有很多直接和間接的觀察者時,將所有的觀察者都通知到會花費很多時間。
(2)、雖然觀察者模式可以隨時使觀察者知道所觀察的對象發(fā)送了變化,但是觀察者模式?jīng)]有相應的機制使觀察者知道所觀察的對象是怎樣發(fā)生變化的。
(3)、如果在被觀察者之間有循環(huán)依賴的話,被觀察者會觸發(fā)它們之間進行循環(huán)調(diào)用,導致系統(tǒng)崩潰,在使用觀察者模式應特別注意這點。

七、.NET 中觀察者模式的實現(xiàn)

我上面寫了一點,“在C#的event中,委托充當了抽象的Observer接口,而提供事件的對象充當了目標對象。委托是比抽象Observer接口更為松耦合的設計。”,其實在Net里面實現(xiàn)的觀察者模式做了一些改變,用委托或者說是事件來實現(xiàn)觀察者模式。事件我們都很明白,我們可以注冊控件的事件,當觸發(fā)控件的動作時候,相應的事件就會執(zhí)行,在事件的執(zhí)行過程中我們就可以做相關的提醒業(yè)務。這里關于觀察者模式在Net里面的實現(xiàn)就不說了,如果大家不明白,可以多看看相關委托或者事件的相關資料。

到此這篇關于.Net行為型設計模式之觀察者模式(Observer)的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • ASP.NET?Core中的通用主機HostBuilder

    ASP.NET?Core中的通用主機HostBuilder

    這篇文章介紹了ASP.NET?Core中的通用主機HostBuilder,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • asp.net Ajax之無刷新評論介紹

    asp.net Ajax之無刷新評論介紹

    asp.net Ajax之無刷新評論介紹;需要的朋友可以參考下
    2012-11-11
  • .Net結(jié)構(gòu)型設計模式之裝飾模式(Decorator)

    .Net結(jié)構(gòu)型設計模式之裝飾模式(Decorator)

    這篇文章介紹了.Net結(jié)構(gòu)型設計模式之裝飾模式(Decorator),文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • 頁面包含的處理

    頁面包含的處理

    頁面包含的處理...
    2006-08-08
  • ASP.NET中 CheckBox復選框控件的使用

    ASP.NET中 CheckBox復選框控件的使用

    本文主要介紹ASP.NET中CheckBox復選框控件的使用,并舉例演示其用法,希望對大家有所幫助。
    2016-04-04
  • ASP.NET?Core?Razor頁面用法介紹

    ASP.NET?Core?Razor頁面用法介紹

    這篇文章介紹了ASP.NET?Core?Razor頁面的用法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-02-02
  • ASP.NET?Core中的wwwroot文件夾

    ASP.NET?Core中的wwwroot文件夾

    這篇文章介紹了ASP.NET?Core中的wwwroot文件夾,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-02-02
  • ASP.NET Core MVC中的局部視圖用法

    ASP.NET Core MVC中的局部視圖用法

    這篇文章介紹了ASP.NET Core MVC局部視圖的用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • Linux?CentOS下docker部署Asp.Net?Core(.Net6)

    Linux?CentOS下docker部署Asp.Net?Core(.Net6)

    這篇文章介紹了Linux?CentOS下docker部署Asp.Net?Core(.Net6)的方法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-12-12
  • 使用Docker部署ASP.NET?Core程序

    使用Docker部署ASP.NET?Core程序

    這篇文章介紹了使用Docker部署ASP.NET?Core程序的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03

最新評論

台中市| 汉川市| 那坡县| 永修县| 洛南县| 民勤县| 神池县| 佳木斯市| 获嘉县| 宿州市| 南康市| 开封市| 湘阴县| 香格里拉县| 灵山县| 南华县| 广水市| 邹平县| 闽侯县| 肥乡县| 剑阁县| 福建省| 咸阳市| 通许县| 泽库县| 云和县| 施秉县| 贵溪市| 乐山市| 积石山| 临颍县| 迁安市| 万载县| 康乐县| 闻喜县| 高青县| 开江县| 靖边县| 临海市| 邹平县| 会同县|