18_觀察者模式

野码發表於2024-03-14

觀察者模式是一種行為型設計模式,它定義了物件之間的一對多依賴關係,使得當一個物件的狀態發生改變時,其相關依賴物件會自動收到通知並更新。

觀察者模式有四個主要角色:

  1. 主題(Subject):定義了觀察者的註冊、刪除和通知方法。主題可以是具體類或介面。

  2. 具體主題(Concrete Subject):繼承或實現了主題,並實現了註冊、刪除和通知方法。具體主題內部維護了一個觀察者列表,並在狀態發生改變時通知觀察者。

  3. 觀察者(Observer):定義了更新方法,用於接收主題的通知並進行相應的處理。觀察者可以是具體類或介面。

  4. 具體觀察者(Concrete Observer):繼承或實現了觀察者,並實現了更新方法。具體觀察者在接收到主題的通知後,執行相應的業務邏輯。

觀察者模式的工作原理如下:

  1. 主題維護了一個觀察者列表,可以在需要的時候註冊、刪除和通知觀察者。

  2. 具體主題實現了主題介面,並在需要的時候呼叫觀察者的更新方法。

  3. 觀察者實現了觀察者介面,並在接收到主題的通知後執行相應的更新操作。

觀察者模式的優點包括:

  1. 解耦了主題和觀察者之間的關係,使得它們可以獨立地變化。

  2. 可以實現一對多的依賴關係,主題的狀態改變時可以同時通知多個觀察者。

  3. 可以方便地增加或刪除觀察者,擴充套件新的觀察者類。

觀察者模式適用於以下場景:

  1. 當一個物件的改變需要同時影響其他物件,並且不希望物件之間緊密耦合時,可以使用觀察者模式。

  2. 當一個抽象模型有兩個方面,其中一個方面依賴於另一個方面,可以使用觀察者模式。

總結而言,觀察者模式透過定義物件之間的一對多依賴關係,實現了當一個物件的狀態發生改變時,其相關依賴物件會自動收到通知並更新。它提供了一種松耦合的方式來處理物件之間的關係,並支援一對多的依賴關係。

案例場景:

貓大叫一聲,老鼠趕緊逃跑,主人醒來開燈看看怎麼回事?

貓就是主題角色(被觀察者),老鼠和主人就是觀察者角色。

Subject

/// <summary>
    /// 被觀察者的抽象基類
    /// </summary>
    public abstract class Subject
    {
        private IList<Observer> _observers = new List<Observer>();//當前主題物件的觀察者集合

        /// <summary>
        /// 新增觀察者
        /// </summary>
        /// <param name="observer"></param>
        public void Attach(Observer observer)
        {
            _observers.Add(observer);
        }

        /// <summary>
        /// 移除觀察者
        /// </summary>
        /// <param name="observer"></param>
        public void Detach(Observer observer)
        {
            _observers.Remove(observer);
        }

        public void Nofity()
        {
            Console.WriteLine("貓突然大叫一聲...喵...");

            foreach (var item in _observers)
            {
                item.Update();
            }
        }
    }

Observer

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

Concrete Subject

public class Cat : Subject
    {
    }

Concrete Observer

public class Mouse : Observer
    {
        public override void Update()
        {
            Console.WriteLine("老鼠:快跑,被老貓發現了...");
        }
    }
public class Master : Observer
    {
        public override void Update()
        {
            Console.WriteLine("主人:我家的貓又叫了,開燈看看怎麼回事?");
        }
    }

呼叫

internal class Client
    {
        public void Start()
        {
            Cat cat = new Cat();
            cat.Attach(new Mouse());
            cat.Attach(new Master());
            cat.Nofity();
        }
    }
static void Main(string[] args)
        {
            new Client().Start();

            Console.ReadKey();
        }

相關文章