C#設計模式系列:觀察者模式(Observer)


  在軟件構建過程中,需要為某些對象建立一種“通知依賴關系”,即一個對象的狀態發生改變,所有的依賴對象都需要得到通知。

1、觀察者模式簡介

1.1>、定義

  定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。

1.2>、使用頻率

  

2、觀察者模式結構

2.1>、結構圖

2.2>、參與者

  觀察者模式參與者:

  ◊ Subject

    ° 抽象的主題,被觀察的對象

    ° 提供Attach和Detach Observer對象的接口

  ◊ ConcreteSubject

    ° 具體的被觀察對象,維持ConcreteSubject狀態。

    ° 當狀態發生變化時,發送消息通知它的觀察者。

  ◊ Observer:抽象的觀察者,定義一個發送變化通知更新的接口。

  ◊ ConcreteObserver

    ° 維持一個對ConcreteSubject對象的引用

    ° 保存subjects狀態

    ° 實現當Observer接口發生變動時,subjects狀態同步更新。

   在觀察者模式中,Subject通過Attach()和Detach()方法添加或刪除其所關聯的觀察者,並通過Notify進行更新,讓每個觀察者都可以觀察到最新的狀態。

3、觀察者模式結構實現

  Observer.cs

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

namespace DesignPatterns.ObserverPattern.Structural
{
    public abstract class Observer
    {
        public abstract void Update();
    }
}

  Subject.cs

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

namespace DesignPatterns.ObserverPattern.Structural
{
    public class Subject
    {
        private List<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();
            }
        }
    }
}

  ConcreteSubject.cs

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

namespace DesignPatterns.ObserverPattern.Structural
{
    public class ConcreteSubject : Subject
    {
        private string _subjectState;

        /// <summary>
        /// Gets or sets subject state
        /// </summary>
        public string SubjectState
        {
            get { return _subjectState; }
            set { _subjectState = value; }
        }
    }
}

  ConcreteObserver.cs

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

namespace DesignPatterns.ObserverPattern.Structural
{
    public 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("Observer {0}'s new state is {1}", _name, _observerState);
        }

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

  Program.cs

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

using DesignPatterns.ObserverPattern.Structural;

namespace DesignPatterns.ObserverPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            // Configure Observer pattern
            ConcreteSubject s = new ConcreteSubject();

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

            // Change subject and notify observers
            s.SubjectState = "ABC";
            s.Notify();
        }
    }
}

  運行輸出:

Observer X's new state is ABC
Observer Y's new state is ABC
Observer Z's new state is ABC
請按任意鍵繼續. . .

4、觀察者模式應用分析

  觀察者模式適用情形:

  ◊ 當一個抽象模型有兩個方面,其中一方面依賴於另一方面。將這二者封裝在獨立的對象中以使它們可以各自獨立地改變和復用。

  ◊ 當對一個對象的改變需要同時改變其他對象,而不需要知道具體有多少對象有待改變。

  ◊ 當一個對象必須通知其他對象,而它又不需要知道其它的通知對象是誰,那些其它對象是誰不影響它發送通知這件事。

  觀察者模式特點:

  ◊ 使用面向對象的抽象,Observer模式使得可以獨立地改變目標與觀察者,從而使二者之間的依賴關系達到松耦合。

  ◊ 目標發送通知時,無需指定觀察者,通知會自動傳播。觀察者自己決定是否需要訂閱通知。

  ◊ 在C#中的Event。委托充當了Observer接口,而提供事件的對象充當了目標對象,委托是比抽象Observer接口更為松耦合的設計。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM