觀察者模式分析、結構圖及基本代碼

來源:互聯網
上載者:User

標籤:觀察者模式   設計   耦合   可擴充   對象   



定義:觀測者模式定義了一種一對多的依賴關係,讓多個觀測者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀測者對象,使它們能夠自動更新自己。
結構圖:


Subject類,可翻譯為主題或抽象通知者,一般用一個抽象類別或者一個介面實現。它把所有對觀察者對象的引用儲存在一個聚集裡,每個主題都可以有任何數量的觀察者。抽象主題提供一個介面,可以增加和刪除觀測者。
Observe類,抽象觀測者,為所有的具體觀察者定義一個介面,在得到主題的通知時更新自己。這個介面叫更新介面。抽象觀察者一般用一個抽象類別或者一個介面實現。更新介面通常包含一個Update()方法,這個方法叫做更新方法。
ConcreteSubject類,叫做具體主題或具體通知者,將有關狀態存入具體觀察者對象;在具體主題的內部狀態改變時,給所有登記過的觀察者發出通知。具體主題角色常用一個具體子類實現。
ConcreteObserver類,具體觀察者,實現抽象觀察者角色所要求的更新介面,以便使本身的狀態與主題的狀體相協調。具體觀察者角色可以儲存一個指向具體主題對象的引用。具體觀察者角色通常用一個具體子類實現。
特點:觀察者模式所做的工作其實就是在解除耦合。讓耦合的雙方都依賴於抽象,而不是依賴於具體。從而使得各自的變化都不會影響到另一邊的變化。
適用地方:當一個對象的改變不要同時改變其他對象的時候,而且它不知道具體有多少對象有待改變時,應該考慮使用觀察者模式。
不足:“抽象通知者”還是依賴“抽象通知者”,也就是說,萬一沒有了抽象觀察者這樣的介面,我這通知的功能就完不成了。另外就是每個具體觀察者,它不一定是‘更新’的方法就調用,就像剛才說的,我希望的是‘工具箱’是隱藏,‘自動視窗’是開啟,這根本就不是同名的方法。這應該就是不足的地方吧。
委託的相關知識:
委託就是一種引用方法的類型。一旦為委託分配了方法,委託將與該方法具有完全相同的行為。委託方法的使用可以像其他任何方法一樣,具有參數和返回值。委託可以看作是對函數的抽象,是函數的‘類’,委託的執行個體將帶便一個具體的函數。
一個委託可以搭載多個方法,所有方法被依次喚醒。更重要的是,它可以使得委派物件所搭載的方法並不需要屬於同一個類。委派物件所搭載的所有方法必須具有相同的原型和形式,也就是擁有相同的參數列表和返回值類型。
基本代碼:

using System;
using System.Collections.Generic;
using System.Text;

namespace 觀察者模式
{
    class Program
    {
        static void Main(string[] args)
        {
            ConcreteSubject s = new ConcreteSubject();

            s.Attach(new ConcreteObserver(s, "X"));
            s.Attach(new ConcreteObserver(s, "Y"));
            s.Attach(new ConcreteObserver(s, "Z"));

            s.SubjectState = "ABC";
            s.Notify();

            Console.Read();

        }
    }


    abstract class Subject
    {
        private IList<Observer> observers = new List<Observer>();

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

    //具體通知者
    class ConcreteSubject : Subject
    {
        private string subjectState;

        //具體通知者狀態
        public string SubjectState
        {
            get { return subjectState; }
            set { subjectState = value; }
        }
    }


    abstract class Observer
    {
        public abstract void Update();
    }

    class ConcreteObserver : Observer
    {
        private string name;
        private string observerState;
        private ConcreteSubject subject;

        public ConcreteObserver(
          ConcreteSubject subject, string name)
        {
            this.subject = subject;
            this.name = name;
        }
        //更新
        public override void Update()
        {
            observerState = subject.SubjectState;
            Console.WriteLine("觀察者{0}的新狀態是{1}",
              name, observerState);
        }

        public ConcreteSubject Subject
        {
            get { return subject; }
            set { subject = value; }
        }
    }

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.