設計模式之觀察者模式與事件委托
觀察者模式:
定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自己更新自己。
觀察者結構模式圖:
結合例子:
static void Main(string[] args)
{
//老板dandan
Boss dandan=new Boss ();
//看股票的同事
StockObserver hongjie=new StockObserver ("張三",dandan );
dandan.Attach (hongjie );
//老板回來
dandan .SubjectState="丹丹回來了";
//發出通知
dandan.Notify ();
}
//通知者接口
interface Subject
{
void Attach(Observer observer);
void Detach(Observer observer);
void Notify();
string SubjectState
{
get;
set;
}
}
//具體通知者類
class Boss:Subject
{
//同事列表
private IList<Observer > observers=new List<Observer>();
private string action;
//增加
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 ();
}
//老板狀態
public string SubjectState
{
get {return action ;}
set {action =value ;}
}
}
//抽象觀察者
abstract class Observer
{
protected string name;
protected Subject sub;
public Observer (string name,Subject sub)
{
this.name =name ;
this.sub =sub ;
}
public abstract void Update();
}
class StockObserver:Observer
{
public StockObserver (string name,Subject sub):base(name,sub )
{
}
public override void Update()
{
Console .WriteLine ("{0}{1}關閉股票行情,繼續工作!",sub.SubjectState ,name );
}
} 這裏用到了一個接口Subject和一個抽象類Observer,這兩個抽象類的使用體現了麵向對象的思想,減少了觀察者與被觀察者之間的耦合度,如果我們直接寫出公司中的boss(被觀察者)和observer(觀察者),那麼他們之間必然會有緊密的聯係,如果被觀察者改變或增加,不管被觀察者類會受到影響,由於被觀察者與觀察者之間的緊耦合,則,觀察者也必然會做相應修改,這不符合依賴倒轉原則和開閉原則。因此,我們需要用觀察者模式,一方麵,觀察者模式具有一個對象的改變可以同時改變其他所有對象;另一方麵,觀察者模式運用接口和抽象類,降低了耦合度,符合設計原則,增強了程序的可維護、擴展和重用性。但這一設計模式仍然有其缺點,因為這種模式的一個特點是抽象通知類還是依賴抽象觀察類的,如果沒有抽象觀察類,那麼通知就無法實現,所以為了避免這一不足,我們就用到了委托事件。
事件委托與觀察者模式:
在之前的博客中,我已經講到了委托,何謂委托?簡單的說委托可以看做是對函數的抽象,是函數的類,委托的實例將代表一個實例,一旦為委托分配了方法,委托將與該方法具有完全相同的行為。在沒有抽像觀察類的情況下,我們可以通過使用事件委托,將同一通知發給所有通知者,即時沒有接口,這一功能同樣可以實現,而且降低了與抽象通知類之間的依賴關係,增加了擴展性、靈活性。
觀察者模式的幾個要點:
1、使用麵向對象的抽象,觀察者模式使得我們可以獨立改變目標與觀察者,從而使得兩者之間的依賴關係達到鬆耦合
2、目標發送通知時,無需指定觀察者,通知會自動傳播。觀察者自己決定是否需要訂閱通知,目標對象對此一無所知。
3、委托充當了抽象的觀察者接口,而提供事件的對象充當餓了目標對象。委托是比抽象觀察者接口更為鬆耦合的設計。
最後更新:2017-04-03 12:55:06