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

首頁 > 編程 > C# > 正文

C# 觀察者模式實例介紹

2020-01-24 03:40:20
字體:
來源:轉載
供稿:網友
觀察者模式

觀察者模式:定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主體對象,這個主題對象在狀態發生變化時,會通知所有觀察者。當一個對象改變需要同時改變其他對象,而且他不知道具體有多少對象需要改變的時候,應該考慮使用觀察者模式。

觀察者結構圖:


使用場景:老板回來通知員工需要進入工作狀態。
定義觀察者的抽象類:
復制代碼 代碼如下:

abstract class Observer
{
protected string name;
protected ISubject sub;
public Observer(string name, ISubject sub)
{
this.name = name;
this.sub = sub;
}
public abstract void Update();
}

看NBA直播的同事:
復制代碼 代碼如下:

//使用OO
class NBAObserver : Observer
{
public NBAObserver(string name, ISubject sub)
: base(name, sub)
{ }
public override void Update()
{
//throw new NotImplementedException();
Console.WriteLine("{0} {1}關閉NBA直播,繼續工作!",sub.SubjectState,name);
}
}
//使用事件和委托
class NBAObserver2
{
private string name;
private ISubject2 sub;
public NBAObserver2(string name, ISubject2 sub)
{
this.name = name;
this.sub = sub;
}
public void CloseStockMarket()
{
Console.WriteLine("{0} {1}關閉NBA直播,繼續工作!", sub.SubjectState, name);
}
}

看股票的同事:
復制代碼 代碼如下:

//使用OO
class StockObserver : Observer
{
public StockObserver(string name, ISubject sub) : base(name,sub)
{ }
public override void Update()
{
//throw new NotImplementedException();
Console.WriteLine("{0} {1}關閉股票行情,繼續工作!",sub.SubjectState,name);
}
}
//使用事件和委托
class StockObserver2
{
private string name;
private ISubject2 sub;
public StockObserver2(string name, ISubject2 sub)
{
this.name = name;
this.sub = sub;
}
public void CloseNBA()
{
Console.WriteLine("{0} {1}關閉股票行情,繼續工作!", sub.SubjectState, name);
}
}

上的身份是訂閱者,下面定義發布者:
復制代碼 代碼如下:

//使用OO
interface ISubject
{
void Attach(Observer observer);
void Detach(Observer observer);
void Notify();
string SubjectState
{
get;
set;
}
}
class Boss : ISubject
{
private IList<Observer> observers = new List<Observer>();
private string action;
public void Attach(Observer observer)
{
observers.Add(observer);
}
public void Detach(Observer observer)
{
observers.Remove(observer);
}
public void Notify()
{
foreach (Observer o in observers)
{
o.Update();
}
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
//使用事件和委托
interface ISubject2
{
void Notify();
string SubjectState
{
get;
set;
}
}
delegate void EventHandler();
class Boss2 : ISubject2
{
public event EventHandler Update;
private string action;
public void Notify()
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}

主函數調用:
復制代碼 代碼如下:

class Program
{
static void Main(string[] args)
{
//觀察者模式OO實現
Boss huhansan = new Boss();
StockObserver tongshi1 = new StockObserver("name1",huhansan);
NBAObserver tonshi2 = new NBAObserver("name2", huhansan);
huhansan.Attach(tongshi1);
huhansan.Attach(tonshi2);
huhansan.SubjectState = "我1回來了";
huhansan.Notify();
//觀察者模式c#事件實現
Boss2 huhansan2 = new Boss2();
StockObserver2 tongshi3 = new StockObserver2("name3", huhansan2);
NBAObserver2 tonshi4 = new NBAObserver2("name4", huhansan2);
huhansan2.Update += new EventHandler(tongshi3.CloseNBA);
huhansan2.Update += new EventHandler(tonshi4.CloseStockMarket);
huhansan2.SubjectState = "我2回來了";
huhansan2.Notify();
Console.ReadKey();
}
}

委托就是一種引用方法的類型,一旦為委托分配了方法,委托將與該方法具有完全相同的行為。委托方法的使用可以像其他任何方法一樣,具有參數和返回值。委托可以看做是對函數的抽象,是函數的一個類,委托實例代表一個具體的函數,而且一個委托可以搭載多個方法,所有方法被依次喚醒。

1 觀察者模式
一個簡單的例子,比如說貓叫,老鼠跑,主人被驚醒。
在不知道觀察者模式之前,我們的代碼可能是這樣的。
復制代碼 代碼如下:

//老鼠類  
class Mouse   
{  
     public void Run()   
     {  
         Console.WriteLine("老鼠跑了!");  
     }  
}  
//主人類  
class Master   
{  
     public void Wake()  
     {  
         Console.WriteLine("主人醒了!");  
     }  
}  
//貓類  
class Cat   
{  
     public void Cry ()  
     {  
         Console.WriteLine("貓叫了!");  
         new Mouse().Run();//貓叫的同時,調用老鼠跑的方法。  
         new Master().Wake();//貓叫的同時,調用主人醒的方法。  
     }  
}  
class Program  
{  
     static void Main(string[] args)  
     {  
         Cat cat = new Cat();  
         cat.Cry();  
         Console.ReadLine();  
     }  
}  

這個代碼基本上能實現所有的功能。但是,這個方法特別不利用擴展,
試想,如果,貓叫后,狗也叫,那是不是也要在貓叫的方法里重新加入狗叫的方法?
或者說,貓叫后,主人他老婆也醒了,是不是也要在貓叫的方法里加入他老婆醒的方法呢?
顯然,這樣的代碼不利用維護,也不是面向對象的代碼。
觀察者模式能夠很好的解決這個問題。
觀察者模式定義對象間的一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于他的對象都得到通知并自動更新。在我們的例子中,貓和老鼠,主人,狗,主人他老婆是一對多的依賴,當貓叫時,所有依賴于它的對象都會自動執行某個操作。
觀察者模式的實現,一般有下面四部分組成。
1.ISubject接口(抽象目標),含方法Notify,Register,UnRegister(名字可以自己任意取名)
2.Subject類(實體目標),實現ISubject接口,一般只有一個
3.IObservable接口(抽象觀察者)。
4 Observer類(實體觀察者),實現IObservable接口,一般有多個。
觀察者模式中的“注冊--通知--注銷”圖示:
1. 觀察者(Observer)將自己(Regiester)注冊到被觀察對象(Subject)中,被觀察對象將觀察者放在一個容器(Container)。Container一般為Ilist,Arraylist等數據結構,存放多個IObservable接口變量。
2.當被觀察對象(Subject)發生變化(如圖中的AskPriceChanged)時,容器(Container)中的所有觀察者(Observer)都得到通知(Notify 方法),此時觀察者會自動執行某些方法。
3.當觀察者不想繼續觀察被觀察者時,可以注銷(UnRegiester方法)
上面的例子中改造后變成:
1.ISubject接口:
復制代碼 代碼如下:

interface ISubject  
    {  
        void Notify();//主題變動時,通知雖有觀察者  
        void Regiester(IObservable o);//觀察者注冊  
        void UnRegiester(IObservable o);//觀察者取消注冊,此時主題發生任何變動,觀察者都不會得到通知。  
    }

2.Subject 類:
復制代碼 代碼如下:

class Cat : ISubject  
   {  
       private IList<IObservable> observers = new List<IObservable>();  
       public void Notify()  
       {  
           foreach (IObservable o in observers) //逐個通知觀察者  
           {  
               o.Action();  
           }  
       }  
       public void Regiester(IObservable o)  
       {  
           if (o != null || !observers.Contains(o))  
           {  
               observers.Add(o);  
           }  
       }  
       public void UnRegiester(IObservable o)  
       {  
           if (observers != null && observers.Contains(o))  
           {  
               observers.Remove(o);  
           }  
       }  
       public void Cry()  
       {  
           Console.WriteLine("貓叫了!");  
           Notify();  
       }  
   }

3. IObservable 接口:
復制代碼 代碼如下:

interface IObservable  
{  
    void Action();//觀察者對主題變動所對應的操作  
}

4.Observer類(2個,Mouse和Master)
復制代碼 代碼如下:

class Mouse : IObservable  
   {  
       public void Action()  
       {  
           Console.WriteLine("鼠跑了!");  
       }  
   }  
   class Master : IObservable  
   {  
       public void Action()  
       {  
           Console.WriteLine("主人醒了!");  
       }  
   }

5.主程序
復制代碼 代碼如下:

Mouse mouse = new Mouse();  
           Master master = new Master();  
           Cat cat = new Cat();  
           cat.Regiester(mouse);  
           cat.Regiester(master);  
           cat.Cry();  
           Console.ReadLine();

這樣就實現了觀察者模式,通過把依賴類注冊到主體類中,當主體類發生變化時,所有依賴類都得到了通知。如果需要擴展,比如說象上面例子的狗也叫了,我們可以定義一個狗類,然后在主程序中把狗對象注冊到貓類中就可以了。如果不想依賴于貓類,也可以通過UnRegiester方法取消綁定。
同時,這也符合設計中的高內聚,低耦合的原則。
。
復制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Text;
namespace Sample
{
    public delegate void CatCallEventHandler();
    class Program
    {
        static void Main(string[] args)
        {
            Cat cat = new Cat();
            Mouse mouse = new Mouse(cat);
            Master master = new Master(mouse);
            cat.Call();
        }
    }
    class Cat
    {
        public event CatCallEventHandler catevent;
        public void Call()
        {
            Console.WriteLine("喵喵.....");
            catevent();
        }
    }
    class Mouse
    {
        public event CatCallEventHandler mouseevent;
        public Mouse(Cat cat)
        {
            cat.catevent += new CatCallEventHandler(this.MouseRun);
        }
        public void MouseRun()
        {
            Console.WriteLine("老鼠跑");
            mouseevent();
        }
    }
    class Master
    {
        public Master(Mouse mouse)
        {
            mouse.mouseevent+=new CatCallEventHandler(this.JingXing);
        }
        public void JingXing()
        {
            Console.WriteLine("主人被驚醒");
        }
    }
}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲视频axxx| 久久视频在线免费观看| 色樱桃影院亚洲精品影院| 亚洲精品一区二区网址| 亚洲精品成人网| 92版电视剧仙鹤神针在线观看| 91在线免费视频| 亚洲午夜小视频| 国产精品久久久久免费a∨大胸| 麻豆国产va免费精品高清在线| 国产日本欧美一区| 国产精品成人观看视频国产奇米| 欧美黑人狂野猛交老妇| 91精品久久久久久久久不口人| www.日本久久久久com.| 亚洲色图五月天| 亚洲国产高潮在线观看| 国产成+人+综合+亚洲欧美丁香花| 最近2019年日本中文免费字幕| 国产一区二区三区毛片| 亚洲片在线资源| 国产性猛交xxxx免费看久久| 91大神福利视频在线| 亚洲国产欧美在线成人app| 国产精品成人一区| 亚洲欧美中文日韩在线v日本| 日韩a**中文字幕| 欧美伊久线香蕉线新在线| 中文字幕在线国产精品| 久久久精品久久| 在线观看日韩欧美| 不用播放器成人网| 亚洲影院色在线观看免费| 欧美另类在线播放| 日韩免费黄色av| 日韩极品精品视频免费观看| 欧美日韩视频免费播放| 亚洲色图在线观看| 欧美诱惑福利视频| 欧美日韩国产页| 日本一区二区三区在线播放| 亚洲国产高清自拍| 午夜精品蜜臀一区二区三区免费| 国产男女猛烈无遮挡91| 亚洲精品永久免费| 亚洲国产日韩欧美在线动漫| 欧美电影免费观看大全| 国产精品成人在线| 久久精品久久精品亚洲人| 亚洲性日韩精品一区二区| 日韩国产高清污视频在线观看| 清纯唯美日韩制服另类| 欧美激情国内偷拍| 亚洲精品国产欧美| 日本19禁啪啪免费观看www| 91精品国产91久久久久久不卡| 国产成人精品优优av| 精品欧美激情精品一区| 欧美激情第99页| 不卡毛片在线看| 欧美成人精品一区二区三区| 亚洲精品综合久久中文字幕| 日韩av最新在线观看| 亚洲成人在线视频播放| 综合欧美国产视频二区| 欧美中文在线观看国产| 日韩欧美中文字幕在线播放| 国产成人精品久久亚洲高清不卡| 在线观看精品自拍私拍| 亚洲一区亚洲二区亚洲三区| 成人免费网站在线观看| 国产色综合天天综合网| 色婷婷av一区二区三区在线观看| 欧美日韩成人网| www高清在线视频日韩欧美| 日韩性生活视频| 日本a级片电影一区二区| 日本久久亚洲电影| 欧美综合激情网| 国产美女高潮久久白浆| 久久久精品一区二区| 5278欧美一区二区三区| 亚洲男人天堂2024| 国产精品视频白浆免费视频| 精品福利视频导航| 亚洲在线观看视频| 欧美在线一级视频| 欧美成年人网站| 精品成人在线视频| 午夜精品美女自拍福到在线| 色av中文字幕一区| 欧美激情第99页| 少妇av一区二区三区| 国产精品老女人视频| 91免费国产视频| 国产午夜精品视频免费不卡69堂| 91九色蝌蚪国产| 性色av一区二区三区| 欧美成人激情视频| 久久久精品影院| 亚洲老头同性xxxxx| 成人做爽爽免费视频| 成人国产在线激情| 亚洲人成绝费网站色www| 亚洲最新视频在线| 国产乱肥老妇国产一区二| 日韩经典一区二区三区| 97香蕉久久超级碰碰高清版| 亚洲tv在线观看| 色婷婷综合久久久久中文字幕1| 欧美极品少妇xxxxx| 国产精品亚洲自拍| 久久亚洲精品中文字幕冲田杏梨| 亚洲xxxxx电影| 久久久免费av| 亚洲精品99久久久久| 国产精品老牛影院在线观看| 久久久久久尹人网香蕉| 亚洲欧美制服综合另类| 国产一区二区三区高清在线观看| 青草青草久热精品视频在线网站| 91精品国产色综合| 欧美日韩激情网| 91国产精品电影| 亚洲精品在线视频| 国产精品极品美女在线观看免费| 在线观看国产成人av片| 国产成人av网址| 亚洲第一精品久久忘忧草社区| 国产成人精品综合| 欧美劲爆第一页| 亚洲黄色www网站| 亚洲电影免费观看高清完整版在线观看| 中文字幕av日韩| 久久久久久国产精品美女| 国产成人在线视频| 国产欧美日韩中文字幕| 欧美午夜女人视频在线| 国产精品专区h在线观看| 欧美日韩免费在线观看| 精品福利在线视频| 久久久久久久色| 欧美中文字幕第一页| 精品高清一区二区三区| 国产精品久久久久久av福利| 日韩免费在线视频| 欧美成人精品激情在线观看| 亚洲精品98久久久久久中文字幕| 97香蕉超级碰碰久久免费软件| 精品视频在线播放| 日韩亚洲成人av在线| 日韩电影中文 亚洲精品乱码| 国产亚洲成av人片在线观看桃| 精品国产乱码久久久久久婷婷| 亚洲欧美激情一区| 欧美在线一区二区三区四| 成人免费淫片视频软件| 欧美黑人一级爽快片淫片高清| 欧美性xxxxx极品娇小| 国产精品高精视频免费| 亚洲一区久久久| 九九九热精品免费视频观看网站| 性色av一区二区三区在线观看| 97视频在线观看免费|