1. 程式人生 > >設計模式之觀察者模式與事件委託

設計模式之觀察者模式與事件委託

        觀察者模式:

                定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某個主題物件。這個主題物件在狀態發生變化時,會通知所有觀察者物件,使它們能夠自己更新自己。

          觀察者結構模式圖:

            

          結合例子:

 static void Main(string[] args)
        {
            //老闆dandan
            Boss dandan=new Boss ();
            //看股票的同事
            StockObserver hongjie=new StockObserver ("張三",dandan );

            dandan.Attach (hongjie );
            //老闆回來
            dandan .SubjectState="丹丹回來了";
             //發出通知
             dandan.Notify ();

        }
        //通知者介面
        interface Subject
        {
            void Attach(Observer observer);
            void Detach(Observer observer);
            void Notify();
            string SubjectState
            {
                get;
                set;
            }
        }
        //具體通知者類
        class Boss:Subject
        {
            //同事列表
            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 ;}
            }
        }
        //抽象觀察者
        abstract class Observer
        {
            protected string name;
            protected Subject sub;

            public Observer (string name,Subject sub)
            {
                this.name =name ;
                this.sub =sub ;
            }

            public abstract void Update();

        }
        class StockObserver:Observer 
        {
            public StockObserver (string name,Subject sub):base(name,sub )
            {
            }
            public override void Update()
            {
 	            Console .WriteLine ("{0}{1}關閉股票行情,繼續工作!",sub.SubjectState ,name );
            }
        }
              這裡用到了一個介面Subject和一個抽象類Observer,這兩個抽象類的使用體現了面向物件的思想,減少了觀察者與被觀察者之間的耦合度,如果我們直接寫出公司中的boss(被觀察者)和observer(觀察者),那麼他們之間必然會有緊密的聯絡,如果被觀察者改變或增加,不管被觀察者類會受到影響,由於被觀察者與觀察者之間的緊耦合,則,觀察者也必然會做相應修改,這不符合依賴倒轉原則和開閉原則。因此,我們需要用觀察者模式,一方面,觀察者模式具有一個物件的改變可以同時改變其他所有物件;另一方面,觀察者模式運用介面和抽象類,降低了耦合度,符合設計原則,增強了程式的可維護、擴充套件和重用性。

           但這一設計模式仍然有其缺點,因為這種模式的一個特點是抽象通知類還是依賴抽象觀察類的,如果沒有抽象觀察類,那麼通知就無法實現,所以為了避免這一不足,我們就用到了委託事件。

          事件委託與觀察者模式:

   在之前的部落格中,我已經講到了委託,何謂委託?簡單的說委託可以看做是對函式的抽象,是函式的類,委託的例項將代表一個例項,一旦為委託分配了方法,委託將與該方法具有完全相同的行為。在沒有抽像觀察類的情況下,我們可以通過使用事件委託,將同一通知發給所有通知者,即時沒有介面,這一功能同樣可以實現,而且降低了與抽象通知類之間的依賴關係,增加了擴充套件性、靈活性。

          觀察者模式的幾個要點:

                      1、使用面向物件的抽象,觀察者模式使得我們可以獨立改變目標與觀察者,從而使得兩者之間的依賴關係達到鬆耦合

                      2、目標傳送通知時,無需指定觀察者,通知會自動傳播。觀察者自己決定是否需要訂閱通知,目標物件對此一無所知。

                      3、委託充當了抽象的觀察者介面,而提供事件的物件充當餓了目標物件。委託是比抽象觀察者介面更為鬆耦合的設計。