設計模式之觀察者模式與事件委託
阿新 • • 發佈:2019-02-06
觀察者模式:
定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某個主題物件。這個主題物件在狀態發生變化時,會通知所有觀察者物件,使它們能夠自己更新自己。
觀察者結構模式圖:
結合例子:
這裡用到了一個介面Subject和一個抽象類Observer,這兩個抽象類的使用體現了面向物件的思想,減少了觀察者與被觀察者之間的耦合度,如果我們直接寫出公司中的boss(被觀察者)和observer(觀察者),那麼他們之間必然會有緊密的聯絡,如果被觀察者改變或增加,不管被觀察者類會受到影響,由於被觀察者與觀察者之間的緊耦合,則,觀察者也必然會做相應修改,這不符合依賴倒轉原則和開閉原則。因此,我們需要用觀察者模式,一方面,觀察者模式具有一個物件的改變可以同時改變其他所有物件;另一方面,觀察者模式運用介面和抽象類,降低了耦合度,符合設計原則,增強了程式的可維護、擴充套件和重用性。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 ); } }
但這一設計模式仍然有其缺點,因為這種模式的一個特點是抽象通知類還是依賴抽象觀察類的,如果沒有抽象觀察類,那麼通知就無法實現,所以為了避免這一不足,我們就用到了委託事件。
事件委託與觀察者模式:
在之前的部落格中,我已經講到了委託,何謂委託?簡單的說委託可以看做是對函式的抽象,是函式的類,委託的例項將代表一個例項,一旦為委託分配了方法,委託將與該方法具有完全相同的行為。在沒有抽像觀察類的情況下,我們可以通過使用事件委託,將同一通知發給所有通知者,即時沒有介面,這一功能同樣可以實現,而且降低了與抽象通知類之間的依賴關係,增加了擴充套件性、靈活性。
觀察者模式的幾個要點:
1、使用面向物件的抽象,觀察者模式使得我們可以獨立改變目標與觀察者,從而使得兩者之間的依賴關係達到鬆耦合
2、目標傳送通知時,無需指定觀察者,通知會自動傳播。觀察者自己決定是否需要訂閱通知,目標物件對此一無所知。
3、委託充當了抽象的觀察者介面,而提供事件的物件充當餓了目標物件。委託是比抽象觀察者介面更為鬆耦合的設計。