說明:
兩種類型的物件,「通知者」和「觀察者」。
訂閱:「通知者」可增減訂閱列表中的「觀察者」
發佈:當有監聽的事件發生時,「通知者」可從訂閱列表中,將事件通知「觀察者」,「觀察者」則會對此事件做相對應的動作。
功用:解除耦合,讓耦合的雙方依賴抽像(接口),而不依賴具體。
範例:
人們看到新聞事件的反應。(屬於酸民類別的只會說"酸",路人類別則只會說"讚")
希望達成如下的效果
static void Main(string[] args) { ConcreteSubject s = new ConcreteSubject(); s.Attach(new ConcreteObserverA(s, "酸民甲")); s.Attach(new ConcreteObserverA(s, "酸民乙")); s.Attach(new ConcreteObserverB(s, "路人丙")); s.Attach(new ConcreteObserverB(s, "路人丁")); s.SubjectState = "ABC"; s.Notify(); Console.WriteLine("-------------------"); s.SubjectState = "DEF"; s.Notify(); Console.Read(); }執行結果:
ABC事件,酸民甲 說:酸酸酸~~
ABC事件,酸民乙 說:酸酸酸~~
ABC事件,路人丙 說:讚讚讚~~
ABC事件,路人丁 說:讚讚讚~~
-------------------
DEF事件,酸民甲 說:酸酸酸~~
DEF事件,酸民乙 說:酸酸酸~~
DEF事件,路人丙 說:讚讚讚~~
DEF事件,路人丁 說:讚讚讚~~
實現重點在於,「觀察者」要實做同一個方法 Update(),如此事件發生時,「通知者」才知道訂閱列表中的「觀察者」都執行 Update()。
(備註:C# 如果用 delegate 委派的方式來做,Update方法名稱就可以也不一樣了)
其餘程式碼
//通知者的抽象類別 abstract class Subject { private IList<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(); } } } //通知者實做範例 class ConcreteSubject : Subject { private string subjectState; //具體通知者狀態 public string SubjectState { get { return subjectState; } set { subjectState = value; } } } //觀察者的抽象類別 abstract class Observer { public abstract void Update(); } //第一種觀察者實做範例 class ConcreteObserverA : Observer { private string name; private ConcreteSubject subject; public ConcreteObserverA(ConcreteSubject subject, string name) { this.subject = subject; this.name = name; } public override void Update() { Console.WriteLine("{0}事件,{1} 說:酸酸酸~~", this.subject.SubjectState, name); } } //第二種觀察者實做範例 class ConcreteObserverB : Observer { private string name; private ConcreteSubject subject; public ConcreteObserverB(ConcreteSubject subject, string name) { this.subject = subject; this.name = name; } public override void Update() { Console.WriteLine("{0}事件,{1} 說:讚讚讚~~", this.subject.SubjectState, name); } }
相關連結:設計模式整理列表
沒有留言:
張貼留言