亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#設計模式之觀察者模式實例講解

2020-01-24 02:19:54
字體:
來源:轉載
供稿:網友

前言

最近開始花點心思研究下設計模式,主要還是讓自己寫的代碼可重用性高、保證代碼可靠性。所謂設計模式,我找了下定義:是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。毫無疑問,設計模式于己于他人于系統都是多贏的;設計模式使代碼編制真正工程化;設計模式是軟件工程的基石脈絡,如同大廈的結構一樣。

為什么要提倡“Design Pattern(設計模式)”?

根本原因是為了代碼復用,增加可維護性。因此這次我們來學習下設計模式,最后會通過C#語言來實現這些設計模式作為例子,深刻理解其中的精髓。

定義

觀察者模式,有時被稱作發布/訂閱模式,觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。

特點

模式中具有的角色

1。 抽象主題(Subject):它把所有觀察者對象的引用保存到一個聚集里,每個主題都可以有任何數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象。

2。 具體主題(ConcreteSubject):將有關狀態存入具體觀察者對象;在具體主題內部狀態改變時,給所有登記過的觀察者發出通知。

3。抽象觀察者(Observer):為所有的具體觀察者定義一個接口,在得到主題通知時更新自己。

4。具體觀察者(ConcreteObserver):實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題狀態協調。

優缺點

優點:

一、通知通信

觀察者模式支持廣播通信。被觀察者會向所有的注冊過的觀察者發出通知。

二、聚耦合

觀察者模式在被觀察者和觀察者之間建立了一個抽象的耦合,被觀察者并不知道任何一個具體的觀察者,只是保存著抽象觀察者的列表,每個具體觀察者都符合一個抽象觀察者的接口。

缺點:

一、時間復雜度

如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。

二、內聯不足

雖然觀察者模式可以隨時使觀察者知道所觀察的對象發送了變化,但是觀察者模式沒有相應的機制使觀察者知道所觀察的對象是怎樣發生變化的。

三、容易出現循環調用

如果在被觀察者之間有循環依賴的話,被觀察者會觸發它們之間進行循環調用,導致系統崩潰,在使用觀察者模式應特別注意這點。

實現思路

下面以xmfdsh發布一篇博客的例子來說明觀察者模式的實現。關注了xmfdsh的朋友們,便可以通過觀察者模式來實時得到博客進行了更新的信息。當一個抽象模型有兩個方面,其中一個方面依賴于另一個方面,將這兩者封裝在獨立的對象中以使它們可以各自獨立地改變和復用的情況下。從方面的這個詞中可以想到,觀察者模式肯定在AOP(面向方面編程)中有所體現。因此這種需求使用觀察者模式來解決就再恰當不過了。

觀察者向目標“訂閱”它的改變,而目標發生改變后就“通知”所有已經“訂閱”了它的改變的觀察者,從而執行“訂閱”的內容。這種機制的好處在于降低耦合度,分工明確,目標只負責在自身狀態發生改變或做出某種行為時向自身的訂閱清單發出“通知”,而不是直接調用觀察者的行為(方法);觀察者只負責向目標“訂閱”它的變化,以及定義自身在收到目標“通知”后所需要做出的具體行為(也就是訂閱的內容)

復制代碼 代碼如下:

// 訂閱號抽象類
    public abstract class Blog
    {
        // 保存訂閱者列表
        private List<IObserver> observers = new List<IObserver>();

        public string Symbol { get; set; }//描寫訂閱號的相關信息
        public string Info { get; set; }//描寫此次update的信息
        public Blog(string symbol, string info)
        {
            this.Symbol = symbol;
            this.Info = info;
        }

        // 對同一個訂閱號,新增和刪除訂閱者的操作
        public void AddObserver(IObserver ob)
        {
            observers.Add(ob);
        }
        public void RemoveObserver(IObserver ob)
        {
            observers.Remove(ob);
        }

        public void Update()
        {
            // 遍歷訂閱者列表進行通知
            foreach (IObserver ob in observers)
            {
                if (ob != null)
                {
                    ob.Receive(this);
                }
            }
        }
    }

    // 具體訂閱號類
    public class MyBlog : Blog
    {
        public MyBlog(string symbol, string info)
            : base(symbol, info)
        {
        }
    }

    // 訂閱者接口
    public interface IObserver
    {
        void Receive(Blog tenxun);
    }

    // 具體的訂閱者類
    public class Subscriber : IObserver
    {
        public string Name { get; set; }
        public Subscriber(string name)
        {
            this.Name = name;
        }

        public void Receive(Blog xmfdsh)
        {
            Console.WriteLine("訂閱者 {0} 觀察到了{1}{2}", Name, xmfdsh.Symbol, xmfdsh.Info);
        }
    }

    // 客戶端測試
    class Program
    {
        static void Main(string[] args)
        {
            Blog xmfdsh = new MyBlog("xmfdsh", "發布了一篇新博客");

            // 添加訂閱者
            xmfdsh.AddObserver(new Subscriber("王尼瑪"));
            xmfdsh.AddObserver(new Subscriber("唐馬儒"));
            xmfdsh.AddObserver(new Subscriber("王蜜桃"));
            xmfdsh.AddObserver(new Subscriber("敖尼瑪"));

            //更新信息
            xmfdsh.Update();
            //輸出結果,此時所有的訂閱者都已經得到博客的新消息
            Console.ReadLine();
        }
    }

運行的效果圖如下:

此類實現方法的類圖如下:

這個類圖是visual studio生成的,可能看起來比較混亂把,這樣的實現就是觀察者模式的實現。任何時候,只要執行了Update方法,便會自動的去通知推送給訂閱了此訂閱號 的用戶,然而在C#中,我們更多的是使用委托與事件來簡化觀察者模式的實現。

復制代碼 代碼如下:

class Program
    {
        // 委托充當訂閱者接口類
        public delegate void NotifyEventHandler(object sender);

        // 抽象訂閱號類
        public class Blog
        {
            public NotifyEventHandler NotifyEvent;
            public string Symbol { get; set; }//描寫訂閱號的相關信息
            public string Info { get; set; }//描寫此次update的信息
            public Blog(string symbol, string info)
            {
                this.Symbol = symbol;
                this.Info = info;
            }

            #region 新增對訂閱號列表的維護操作
            public void AddObserver(NotifyEventHandler ob)
            {
                NotifyEvent += ob;
            }
            public void RemoveObserver(NotifyEventHandler ob)
            {
                NotifyEvent -= ob;
            }

            #endregion

            public void Update()
            {
                if (NotifyEvent != null)
                {
                    NotifyEvent(this);
                }
            }
        }

        // 具體訂閱號類
        public class MyBlog : Blog
        {
            public MyBlog(string symbol, string info)
                : base(symbol, info)
            {
            }
        }

        // 具體訂閱者類
        public class Subscriber
        {
            public string Name { get; set; }
            public Subscriber(string name)
            {
                this.Name = name;
            }

            public void Receive(Object obj)
            {
                Blog xmfdsh = obj as Blog;

                if (xmfdsh != null)
                {
                    Console.WriteLine("訂閱者 {0} 觀察到了{1}{2}", Name, xmfdsh.Symbol, xmfdsh.Info);
                }
            }
        }

        static void Main1(string[] args)
        {
            Blog xmfdsh = new MyBlog("xmfdsh", "發布了一篇新博客");
            Subscriber wnm = new Subscriber("王尼瑪");
            Subscriber tmr = new Subscriber("唐馬儒");
            Subscriber wmt = new Subscriber("王蜜桃");
            Subscriber anm = new Subscriber("敖尼瑪");

            // 添加訂閱者
            xmfdsh.AddObserver(new NotifyEventHandler(wnm.Receive));
            xmfdsh.AddObserver(new NotifyEventHandler(tmr.Receive));
            xmfdsh.AddObserver(new NotifyEventHandler(wmt.Receive));
            xmfdsh.AddObserver(new NotifyEventHandler(anm.Receive));

            xmfdsh.Update();

            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine();

            Console.WriteLine("移除訂閱者王尼瑪");
            xmfdsh.RemoveObserver(new NotifyEventHandler(wnm.Receive));
            xmfdsh.Update();

            Console.ReadLine();
        }
    }

運行的結果:

類圖:

總結

到這里,觀察者模式就講完了,觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象可以同時監聽某一個主題對象,這個主題對象在發生狀態變化時,會通知所有觀察者對象,使它們能夠自動更新自己,因此在一些需求上是當一個對象的改變需要同時改變多個其他對象的時候,且不知道多少個對象需要去通知改變的時候,觀察者模式就成了首選,這種模式的用的最多的,在我的開發經歷中便是windows phone手機客戶端的開發了,經常要用到這類的委托事件的處理,用多了后發現就習以為常,這種模式也就沒那么稀奇了。

源碼下載地址:http://xiazai.VeVB.COm/201410/tools/ConsoleApplication2.rar

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美野外猛男的大粗鳮| 国产主播在线一区| 成人免费视频a| 在线视频欧美性高潮| 亚洲图片在线综合| 成人av.网址在线网站| 国产精品第一页在线| 国产精品亚洲аv天堂网| 亚洲第一网站免费视频| 精品久久久久久| 欧美在线观看www| 国产日韩中文字幕在线| 色综合久久精品亚洲国产| 亚洲国产日韩欧美在线99| 亚洲天堂成人在线| 国产日韩中文在线| 91精品在线一区| www.99久久热国产日韩欧美.com| 欧美在线视频一区| 久久久久久久久爱| 亚洲直播在线一区| 亚洲人午夜精品免费| 精品电影在线观看| 国产精品1区2区在线观看| 成人国产在线视频| 高清欧美一区二区三区| 国产精品久久久久久av福利| 亚洲欧洲日本专区| 国产成+人+综合+亚洲欧美丁香花| 最近2019中文字幕大全第二页| 亚洲黄色av网站| 中文亚洲视频在线| 午夜精品一区二区三区av| 欧美日韩中文字幕综合视频| 国产区精品视频| 国产日产欧美a一级在线| 免费av在线一区| 91高清视频在线免费观看| 国产精品国产三级国产专播精品人| 国产噜噜噜噜久久久久久久久| 日韩欧美国产免费播放| 久久久av一区| 久久精品久久久久久国产 免费| 精品久久久久久久中文字幕| 国产精品91视频| 亚洲影院色在线观看免费| 日本欧美精品在线| 清纯唯美亚洲激情| 亚洲色图第一页| 久久久国产精品免费| 日韩中文字幕久久| 国产日韩欧美自拍| 色一情一乱一区二区| 成人av在线天堂| 国产精品爽爽ⅴa在线观看| 欧洲日韩成人av| 久久五月天色综合| 日韩电影免费在线观看中文字幕| 国产精品∨欧美精品v日韩精品| 亚洲欧美自拍一区| 欧美日韩人人澡狠狠躁视频| 国产日韩欧美日韩大片| 精品久久在线播放| 亚洲另类激情图| 亚洲国产古装精品网站| 久久亚洲私人国产精品va| 成人激情黄色网| 清纯唯美日韩制服另类| 在线看片第一页欧美| 亚洲自拍小视频免费观看| 午夜精品久久久久久久久久久久久| 午夜免费久久久久| 另类少妇人与禽zozz0性伦| 最近的2019中文字幕免费一页| 97视频在线免费观看| 欧美日韩性视频| 精品视频—区二区三区免费| 欧美激情精品久久久久久黑人| 日韩美女视频免费看| 奇米一区二区三区四区久久| 国产精品一区二区久久国产| 97视频在线免费观看| 欧美色videos| 最近日韩中文字幕中文| 最近更新的2019中文字幕| 亚洲精品小视频在线观看| 亚洲精品电影网在线观看| 欧美限制级电影在线观看| 国产精品情侣自拍| 国产精品88a∨| 久久精品这里热有精品| 久久人人爽国产| 欧美午夜精品久久久久久人妖| 国产午夜精品一区理论片飘花| 揄拍成人国产精品视频| 国产成人精彩在线视频九色| 欧美激情精品久久久久久变态| 亚洲人a成www在线影院| 另类视频在线观看| 亚洲国产成人爱av在线播放| 亚洲福利在线看| 国产精品你懂得| 成人免费高清完整版在线观看| 热久久美女精品天天吊色| 欧美性黄网官网| 日韩在线视频观看正片免费网站| 色伦专区97中文字幕| 一夜七次郎国产精品亚洲| www高清在线视频日韩欧美| 欧美日韩不卡合集视频| 国产精品jizz在线观看麻豆| 一区二区成人精品| 国产成人aa精品一区在线播放| 久久久久久成人| 激情懂色av一区av二区av| 在线电影中文日韩| 91精品国产色综合久久不卡98| 最近2019年手机中文字幕| 国产精品美女999| 色偷偷91综合久久噜噜| 国产97在线播放| 成人黄色av播放免费| 不用播放器成人网| 岛国av一区二区| 亚洲毛茸茸少妇高潮呻吟| 欧美一区二区三区免费视| 国产精品成人久久久久| 国产一区二区三区直播精品电影| 国产香蕉一区二区三区在线视频| 亚洲人成绝费网站色www| 国外色69视频在线观看| 国产精品亚发布| 欧美wwwxxxx| 日韩极品精品视频免费观看| 成人写真视频福利网| 国产精品自在线| 成人黄色午夜影院| 狠狠综合久久av一区二区小说| 91精品国产91久久久久久吃药| 中文字幕精品—区二区| 国产999在线观看| 国产999精品视频| 91av在线播放| 久久久精品欧美| 国产美女高潮久久白浆| 97热在线精品视频在线观看| 久久亚洲影音av资源网| 欧美激情国产高清| 2019中文字幕在线免费观看| 亚洲欧洲自拍偷拍| 亚洲精品欧美极品| 一本一道久久a久久精品逆3p| 欧美激情日韩图片| 国模精品一区二区三区色天香| 国产精品视频专区| 秋霞午夜一区二区| 97欧美精品一区二区三区| 亚洲美女在线观看| 日韩成人中文字幕在线观看| 91视频九色网站| 日韩精品在线免费观看视频| 亚洲午夜性刺激影院| 欧美激情综合色综合啪啪五月| 成人精品视频99在线观看免费|