物件導向設計模式-觀察者模式(Observer Pattern)

此篇介紹OOP Design Pattern-觀察者模式(Observer Pattern),因應不同的情境需求使用不同的設計模式,藉此來練習且讓頭腦熟練這樣的技巧,一邊實作一邊紀錄留下足跡。

繼上一篇策略模式-Strategy Pattern後陸陸續續新增上架新學習到的設計模式。

這次介紹觀察者模式-Observer Pattern

設計模式-觀察者模式(Observer Pattern)

又可稱之為: publish-subscribe (發佈-訂閱) 模式,定義物件之間一對多的關係,當物件狀態改變時,所有訂閱者皆會收到訊息並更新。

我們用的Youtube訂閱為例子,當觀眾看了阿嘎的頻道很尬意,按下訂閱此頻道,當阿嘎下次有發新的影片就會通知各個觀眾,而觀眾可以隨時的取消訂閱,這裡阿嘎頻道就是所謂的出版者,觀眾則是訂閱者。

 

//出版者介面
public interface IPublish
{
    void registerObserver(ISubscribe io);
    void removeObserver(ISubscribe io);
    void notifyObserver(string message);
}
public class Channel : IPublish
{
    private List<ISubscribe> subscribeList;
    private string cName = "";
    public Channel(string name)
    {
        subscribeList = new List<ISubscribe>();
        cName = name;
    }
    //加入訂閱
    public void registerObserver(ISubscribe io)
    {
        subscribeList.Add(io);
    }
    //退訂閱
    public void removeObserver(ISubscribe io)
    {
        subscribeList.Remove(io);
    }
    //通知訂閱
    public void notifyObserver(string message)
    {
        foreach (ISubscribe subscribe in subscribeList)
        {
            subscribe.Notify(cName + message);
        }
    }
}

 

//訂閱者介面
public  interface ISubscribe
{
    void Notify(string message);
}
public class Audience : ISubscribe
{
    private string info = "";
    private string aName = "";
    public Audience(string name)
    {
        aName = name;
    }
    public void Notify(string message)
    {
        info = message;
        display();
    }
    protected void display()
    {
        Console.WriteLine(aName + " receive : " + info);            
    }
}

 

實作:

private static void Main(string[] args)
{
    //建立阿嘎頻道
    Channel GaChannel = new Channel("阿嘎頻道");
    //建立Alex觀眾
    Audience AlexAudience = new Audience("Alex");
    //Alex觀眾訂閱阿嘎頻道
    GaChannel.registerObserver(AlexAudience);
    //建立Amy觀眾
    Audience AmyAudience = new Audience("Amy");
    //Amy觀眾訂閱阿嘎頻道
    GaChannel.registerObserver(AmyAudience);
    //阿嘎頻道發布第一部新影片
    GaChannel.notifyObserver("上傳了我愛台灣影片#1。");
    //Amy觀眾退訂閱
    GaChannel.removeObserver(AmyAudience);
    //阿嘎頻道發布第二部新影片
    GaChannel.notifyObserver("上傳了我愛彭政閔影片#2。");
    Console.Read();
}

 

結果:

總結:

以程式面來說我們利用List<ISubscribe>紀錄所有訂閱者(物件之間一對多的關係),當出版者利用notifyObserver()發送新影片訊息(狀態改變),所有訂閱觀眾Notify()接收到訊息。

 

有任何問題可在下方留言讓我知道。

謝謝

 

下一篇裝飾者模式-Decorate Pattern

 

參考資料

書籍:Head First Design Patterns-深入淺出 設計模式。