【設計模式】——觀察者模式
阿新 • • 發佈:2019-01-04
【觀察者模式】
觀察者模式定義了一種一對多的依賴關係,讓多個觀察物件同時監聽一個主題物件。這個主題物件再狀態發生變換時候,會通知所有觀察者物件,使他們能夠自動更新自己。
【介紹】
-
主要解決:一個物件改變狀態給其他物件通知的問題
-
何時使用:一個物件(目標物件)的狀態發生變化,所有的依賴物件(觀察者物件)都將得通知,進行廣播通知
-
如何解決:使用面向物件技術,可以將這種依賴關係弱化
-
關鍵程式碼:在抽象類裡有一個ArraList存放著觀察者
-
優點:觀察者和被觀察者是抽象耦合的;建議一套觸發機制
-
缺點:1、如果一個被觀察者物件有很多的直接和間接的觀察者,將所有的觀察者都通知到會花費很多時間。2、如果觀察者和被觀察者之間有迴圈依賴,被觀察者會觸發他們之間進行迴圈呼叫,可能導致系統崩潰。3、觀察者模式沒有相應的機制讓觀察者知道所觀察的目物件是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化
-
注意事項:避免迴圈引用;如果順序執行,某一觀察者錯誤會導致系統卡死,一部採用非同步方式
【實現】
步驟一:subject類,為抽象主題提供一個介面
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(); } } }
步驟二:observer類,抽象觀察者
abstract class Observer
{
public abstract void Update();
}
步驟三:ConcreteSubject類,具體主題或者具體通知者
class ConcreteSubject:Subject { private string subjectState; //具體被觀察者狀態 public string SubjectState { get { return subjectState; } set { subjectState = value; } } }
步驟四:ConcreteObserver類,具體觀察者
class ConcreteObserver:Observer
{
private string name;
private string observerState;
private ConcreteSubject subject;
public ConcreteObserver(ConcreteSubject subject,string name)
{
this.subject = subject;
this.name = name;
}
public override void Update()
{
observerState = subject.SubjectState;
Console.WriteLine("觀察者{0}的新狀態是{1}",name ,observerState);
}
public ConcreteSubject Subject
{
get { return subject; }
set { subject = value; }
}
}
步驟五:客戶端程式碼
static void Main(string[] args)
{
ConcreteSubject s = new ConcreteSubject();
s.Attach(new ConcreteObserver(s, "張三"));
s.Attach(new ConcreteObserver(s,"李四"));
s.SubjectState = "鬥地主";
s.Notify();
Console.Read();
}
【總結】