新的一週又開始了,這周邊的又有點浮躁,時刻提醒自己沉下心來好好學習!今天學習的是觀察者模式,不過真心感覺挺抽象的。
觀察者模式(Observer)
定義:觀察者模式(有時又被稱爲發佈-訂閱模式、模型-視圖模式、源-收聽者模式或從屬者模式),定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。
角色:
1 抽象主題(Subject):它把所有觀察者對象的引用保存到一個聚集裏,每個主題都可以有任何數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象。
2 具體主題(ConcreteSubject):將有關狀態存入具體觀察者對象;在具體主題內部狀態改變時,給所有登記過的觀察者發出通知。
3 抽象觀察者(Observer):爲所有的具體觀察者定義一個接口,在得到主題通知時更新自己。
4 具體觀察者(ConcreteObserver):實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題狀態協調。
觀察者設計模式定義了對象間的一種一對多的依賴關係,以便一個對象的狀態發生變化時,所有依賴於它的對象都得到通知並自動刷新。
類圖:
代碼:
Subject.cs
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();
}
}
}
ConcreteSubject.cs
class ConcreteSubject : Subject
{
private string subjectState;
public string SubjectState
{
get { return subjectState; }
set { subjectState = value; }
}
}
Observer.cs
abstract class Observer
{
public abstract void Update();
}
ConcreteObserver.cs
class ConcreteObserver : Observer
{
private string name;
private string observerState;
private ConcreteSubject subject;
internal ConcreteSubject Subject
{
get { return subject; }
set { subject = value; }
}
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);
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
ConcreteSubject sb = new ConcreteSubject();
sb.Attach(new ConcreteObserver(sb, "X"));
sb.Attach(new ConcreteObserver(sb, "Y"));
sb.Attach(new ConcreteObserver(sb, "Z"));
sb.SubjectState = "ABC";
sb.Notify();
Console.ReadKey();
}
}
優點
觀察者模式解除了主題和具體觀察者的耦合,讓耦合的雙方都依賴於抽象,而不是依賴具體。從而使得各自的變化都不會影響另一邊的變化。
缺點
依賴關係並未完全解除,抽象通知者依舊依賴抽象的觀察者。
適用場景
當一個對象的改變需要給變其它對象時,而且它不知道具體有多少個對象有待改變時。
一個抽象某型有兩個方面,當其中一個方面依賴於另一個方面,這時用觀察者模式可以將這兩者封裝在獨立的對象中使它們各自獨立地改變和複用。