此篇介紹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-深入淺出 設計模式。