說明:
兩種類型的物件,「通知者」和「觀察者」。
訂閱:「通知者」可增減訂閱列表中的「觀察者」
發佈:當有監聽的事件發生時,「通知者」可從訂閱列表中,將事件通知「觀察者」,「觀察者」則會對此事件做相對應的動作。
功用:解除耦合,讓耦合的雙方依賴抽像(接口),而不依賴具體。
範例:
人們看到新聞事件的反應。(屬於酸民類別的只會說"酸",路人類別則只會說"讚")
希望達成如下的效果
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);
}
}
相關連結:設計模式整理列表
沒有留言:
張貼留言