1. 程式人生 > >【C#設計模式-觀察者模式】

【C#設計模式-觀察者模式】

一.基本簡介:觀察者設計模式定義了物件間的一種一對多的依賴關係,以便一個物件的狀態發生變化時,所有依賴於它的物件都得到通知並自動重新整理。在現實生活中的可見觀察者模式,例如,微信中的訂閱號,訂閱部落格和QQ微博中關注好友,這些都屬於觀察者模式的應用。

二.實現:比如熱水器在燒水的過程中,當水溫即將燒開時,會發出報警的聲音,顯示器上會出現溫度監控

    public interface IObserver
    {
        /// <summary>
        /// 更新自身狀態
        /// </summary>
        void Update(int temp);
    }
    /// <summary>
    /// IObserverable介面
    /// </summary>
    public interface IObservable
    {
        /// <summary>
        /// 註冊IObserver
        /// </summary>
        /// <param name="obj"></param>
        void Register(IObserver obj);
        /// <summary>
        /// 取消IObserver的註冊
        /// </summary>
        /// <param name="obj"></param>
        void Unregister(IObserver obj);
    }
    /// <summary>
    /// 抽象基類
    /// </summary>
    public abstract class SubjectBase:IObservable
    {
        private List<IObserver> container = new List<IObserver>();

        public void Register(IObserver obj)
        {
            container.Add(obj);
        }

        public void Unregister(IObserver obj)
        {
            container.Remove(obj);
        }

        /// <summary>
        /// 通知所有註冊了的Observe
        /// </summary>
        protected virtual void Notify(int temp)
        {
            foreach (IObserver observer in container)
            {
                //呼叫Observer的Update()方法
                observer.Update(temp); 
            }
        }
    }
    public class Heater:SubjectBase
    {
        private int temp;//水溫

        protected virtual void OnBioiled()
        {
            base.Notify(temp);
        }

        public void GetMonitoring()
        {
            for (int i = 0; i <= 99; i++)
            {
                temp = i + 1;
                if (temp > 95)
                {
                    OnBioiled();
                }
            }
        }
    }
    public class Alarm:IObserver
    {
        public void Update(int temp)
        {
            if (temp == 100)
            {
                Console.WriteLine("水燒開了"+temp);
            }
            else
            {
                Console.WriteLine("開始報警,水快燒開了>> " + temp);
            }
        }
    }
    public class Screen:IObserver
    {
        public void Update(int temp)
        {
            if (temp == 100)
            {
                Console.WriteLine("水燒開了" + temp);
            }
            else
            {
                Console.WriteLine("水快燒開了>> " + temp);
            }
        }
    }
    /// <summary>
    /// C#設計模式-觀察者模式
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Heater heater = new Heater();
            heater.Register(new Screen());
            heater.Register(new Alarm());
            heater.GetMonitoring();
        }
    }

在上面的例子中,熱水器是Subject,報警器和顯示器是Observer,報警器和顯示器關心熱水器中的水溫。
優點:
觀察者模式實現了表示層和資料邏輯層的分離,並定義了穩定的更新訊息傳遞機制,並抽象了更新介面,使得可以有各種各樣不同的表示層,即觀察者。
觀察者模式在被觀察者和觀察者之間建立了一個抽象的耦合,被觀察者並不知道任何一個具體的觀察者,只是儲存著抽象觀察者的列表,每個具體觀察者都符合一個抽象觀察者的介面。
觀察者模式支援廣播通訊。被觀察者會向所有的註冊過的觀察者發出通知。
缺點:
如果一個被觀察者有很多直接和間接的觀察者時,將所有的觀察者都通知到會花費很多時間。
雖然觀察者模式可以隨時使觀察者知道所觀察的物件傳送了變化,但是觀察者模式沒有相應的機制使觀察者知道所觀察的物件是怎樣發生變化的。
如果在被觀察者之間有迴圈依賴的話,被觀察者會觸發它們之間進行迴圈呼叫,導致系統崩潰,在使用觀察者模式應特別注意這點。

觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件可以同時監聽某一個主題物件,這個主題物件在發生狀態變化時,會通知所有觀察者物件,使它們能夠自動更新自己,解決的是“當一個物件的改變需要同時改變多個其他物件”的問題。