永久免费看黄A片无码软件,japanese 在线观看国产,强奷高H猛烈失禁潮喷播放,亚洲成精品自拍

rexian

咨詢電話:023-6276-4481

熱門文章

聯(lián)系方式

電 話:023-6276-4481

郵箱:broiling@qq.com

地址:重慶市南岸區(qū)亞太商谷6幢25-2

當(dāng)前位置:網(wǎng)站首頁(yè) > 技術(shù)文章 > 設(shè)計(jì)模式-觀察者模式

設(shè)計(jì)模式-觀察者模式

編輯:kangkang 發(fā)表時(shí)間:2017-08-21 12:10:56
kangkang

場(chǎng)景描述

員工上班期間,很多同事會(huì)趁老板不在偷偷看股票,但是又害怕老板突然回來(lái)出現(xiàn)在身后,而被逮個(gè)正著。于是乎。公司同事開(kāi)始和前臺(tái)小美眉不斷獻(xiàn)殷勤,希望前臺(tái)能在老板會(huì)公司的時(shí)候打個(gè)電話到部門辦公室,這樣大家就都知道老板回來(lái)了,可以馬上把股票界面關(guān)掉。
其實(shí)像上面這個(gè)場(chǎng)景就是一個(gè)典型的觀察者模式案例。我們先把它寫(xiě)成程序。
前臺(tái)就相當(dāng)于觀察者模式當(dāng)中的主題,它負(fù)責(zé)給所有觀察者也就是公司同事發(fā)送老板回來(lái)了的消息。

代碼實(shí)現(xiàn)

首先定義一個(gè)主題接口

//主題接口
    interface ISubject
    {        //增加觀察者,公司同事
        void Attach(Observer observer);        //移除觀察者
        void Detach(Observer observer);        //消息(如果老板回來(lái)了,馬上向所有觀察者也就是公司同事發(fā)送消息)
        void Notify();        //發(fā)布狀態(tài)(老板是否回來(lái)的狀態(tài))
        string SubjectState
        {            get;            set;
        }
    }

然后定義一個(gè)具體的主題,這里就是前臺(tái),讓它繼承于主題接口

//具體主題
    class Secretary : 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);
        }        //遍歷所有觀察者,給每一個(gè)觀察者發(fā)送消息
        public void Notify()        {            foreach (Observer o in observers)
            {
                o.Update();
            }
        }        public string SubjectState
        {            get { return action; }            set { action = value; }
        }
    }

接著定義抽象觀察者

//抽象觀察者
    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();
    }

這里之所以要定義抽象觀察者,是為了提高程序的擴(kuò)展性,因?yàn)椴灰欢ㄋ型露伎垂善保热邕€有同事看NBA的,那只要讓他們都繼承與這個(gè)抽象類就好了

//看股票的同事類
class StockObserver : Observer
    {
        public StockObserver(string name, ISubject sub) :base(name, sub )        {

        }

        public override void Update()
        {
            Console.WriteLine("{0},{1},closeStock",sub.SubjectState,name);
        }
    }
//看NBA的同事類
class NBAObserver : Observer
    {
        public NBAObserver(string name, ISubject sub)
            : base(name, sub)        {

        }

        public override void Update()
        {
            Console.WriteLine("{0},{1},closeNBA", sub.SubjectState, name);
        }
    }

客戶端

static void Main(string[] args)
        {
            Secretary sec = new Secretary();
            sec.Attach(new StockObserver("allen",sec));
            sec.Attach(new NBAObserver("kobe", sec));

            sec.SubjectState = "boss is back";

            sec.Notify();

        }

類圖

309352-20170820202158412-1057193155.png

觀察者模式所做的工作其實(shí)就是在解除耦合。讓耦合的雙方都依賴于抽象,而不是依賴于具體。從而使得各自的變化都不會(huì)影響另一邊的變化。

用委托實(shí)現(xiàn)觀察者模式

在具體應(yīng)用中,不大會(huì)出現(xiàn)所有的觀察者都是具備同一行為(關(guān)閉股票或者NBA界面),可能不同的觀察者會(huì)有完全不同的行為,所以這個(gè)時(shí)候我們就會(huì)通過(guò)委托來(lái)實(shí)現(xiàn)觀察者模式
修改前臺(tái)主題類

//定義一個(gè)委托delegate void EventHandler();    class Secretary : ISubject
    {        //聲明一個(gè)事件,類型為委托EventHandler
        public event EventHandler Update;        private string action;        public void Notify()        {
            Update();
        }        public string SubjectState
        {            get { return action; }            set { action = value; }
        }
    }

股票同事類中,可以用自己定義的行為

class StockObserver : Observer
    {
        public StockObserver(string name, ISubject sub) :base(name, sub )        {

        }
        //自己定義的方法
        public void CloseStockMarket()
        {
            Console.WriteLine("{0},{1},closeStock",sub.SubjectState,name);
        }
    }

NBA同事類也一樣

class NBAObserver : Observer
    {
        public NBAObserver(string name, ISubject sub)
            : base(name, sub)        {

        }

        public void CloseNBADirectSeeding()
        {
            Console.WriteLine("{0},{1},closeNBA", sub.SubjectState, name);
        }
    }

客戶端

static void Main(string[] args)
        {
            Secretary sec = new Secretary();
            
            StockObserver stock = new StockObserver("allen",sec);
            NBAObserver nba = new NBAObserver("kobe",sec);

            sec.SubjectState = "back";            //將各自的行為添加到事件中
            sec.Update += new EventHandler(stock.CloseStockMarket);
            sec.Update += new EventHandler(nba.CloseNBADirectSeeding);

            sec.Notify();
        }

觀察者模式的應(yīng)用場(chǎng)景:

1、 對(duì)一個(gè)對(duì)象狀態(tài)的更新,需要其他對(duì)象同步更新,而且其他對(duì)象的數(shù)量動(dòng)態(tài)可變。
2、 對(duì)象僅需要將自己的更新通知給其他對(duì)象而不需要知道其他對(duì)象的細(xì)節(jié)。

觀察者模式的優(yōu)點(diǎn):

1、 Subject和Observer之間是松偶合的,分別可以各自獨(dú)立改變。
2、 Subject在發(fā)送廣播通知的時(shí)候,無(wú)須指定具體的Observer,Observer可以自己決定是否要訂閱Subject的通知。
3、 遵守大部分GRASP原則和常用設(shè)計(jì)原則,高內(nèi)聚、低偶合。