一個對象的動作觸發多個對象的行為,通過觀察者可以去掉對象的依賴,支持各種自定義和擴展。 觀察者模式,還要從那隻申請的貓開始說起。 貓叫一聲之後觸發: Baby Cry()、Brother Trun()、Dog Wang()、Father Roar()、Mothor Whisper()、Mouse R ...
一個對象的動作觸發多個對象的行為,通過觀察者可以去掉對象的依賴,支持各種自定義和擴展。
觀察者模式,還要從那隻申請的貓開始說起。
貓叫一聲之後觸發:
Baby Cry()、Brother Trun()、Dog Wang()、Father Roar()、Mothor Whisper()、Mouse Run()、Neighbour Awake()、Stealer Hide().......
下麵代碼是這些觸發類:
public class Baby { public void Cry() { Console.WriteLine("{0} Cry", this.GetType().Name); } } public class Brother { public void Turn() { Console.WriteLine("{0} Turn", this.GetType().Name); } } public class Chicken { public void Woo() { Console.WriteLine("{0} Woo", this.GetType().Name); } } public class Dog { public void Wang() { Console.WriteLine("{0} Wang", this.GetType().Name); } } public class Father { public void Roar() { Console.WriteLine("{0} Roar", this.GetType().Name); } } public class Mother { public void Whisper() { Console.WriteLine("{0} Whisper", this.GetType().Name); } } public class Mouse { public void Run() { Console.WriteLine("{0} Run", this.GetType().Name); } } public class Neighbor { public void Awake() { Console.WriteLine("{0} Awake", this.GetType().Name); } } public class Stealer { public void Hide() { Console.WriteLine("{0} Hide", this.GetType().Name); } }View Code
然後,貓叫一聲,觸發這些動作:
public class Cat { public void Miao() { Console.WriteLine("{0} Miao.....", this.GetType().Name); new Mouse().Run();//依賴 new Chicken().Woo(); new Baby().Cry(); new Brother().Turn(); new Dog().Wang(); new Father().Roar(); new Mother().Whisper(); //new Mouse().Run(); new Neighbor().Awake(); //new Stealer().Hide(); } }
這樣寫,功能是實現了,但是依賴太多,任何一個對象改動,都會導致Cat類變化,違背了單一職責,不僅自己Miao,還要觸發各種動作,不穩定,加一個/減一個/調整順序,Cat都得改。
Cat職責:
1、Miao()
2、觸發一些列動作,這其實就是需求
3、實現上,其實多了一個,指定動作
Cat不穩定的原因,在Miao()方法裡面的一些對象。
這個時候就要甩鍋大法了,把鍋丟出去與,只管自己,把不穩定的地方移出去,自己只寫穩定的,這樣能保證自身的穩定。
定義一個介面,把這些動作抽象出一個Action(),只是為了把多個對象產生關係,方便保存和調用,方法本身其實沒用的:
public interface IObserver { void Action(); }
讓上面那些Miao一聲後需要觸發的動作類,實現這個介面:
public class Baby : IObserver { public void Action() { this.Cry(); } public void Cry() { Console.WriteLine("{0} Cry", this.GetType().Name); } } public class Brother : IObserver { public void Action() { this.Turn(); } public void Turn() { Console.WriteLine("{0} Turn", this.GetType().Name); } } public class Chicken : IObserver { public void Action() { this.Woo(); } public void Woo() { Console.WriteLine("{0} Woo", this.GetType().Name); } } public class Dog : IObserver { public void Action() { this.Wang(); } public void Wang() { Console.WriteLine("{0} Wang", this.GetType().Name); } } public class Father : IObserver { public void Action() { this.Roar(); } public void Roar() { Console.WriteLine("{0} Roar", this.GetType().Name); } } public class Mother : IObserver { public void Action() { this.Whisper(); } public void Whisper() { Console.WriteLine("{0} Whisper", this.GetType().Name); } } public class Mouse : IObserver { public void Action() { this.Run(); } public void Run() { Console.WriteLine("{0} Run", this.GetType().Name); } } public class Neighbor : IObserver { public void Action() { this.Awake(); } public void Awake() { Console.WriteLine("{0} Awake", this.GetType().Name); } } public class Stealer : IObserver { public void Action() { this.Hide(); } public void Hide() { Console.WriteLine("{0} Hide", this.GetType().Name); } }View Code
Cat這個類就可以修改成如下,使用集合或者事件都是可以的:
public class Cat { //Cat不穩定--這一堆對象--甩鍋--自己不寫讓別人傳遞 private List<IObserver> _ObserverList = new List<IObserver>(); public void AddObserver(IObserver observer) { this._ObserverList.Add(observer);
MiaoHandler += observer.Action; } public void MiaoObserver() { Console.WriteLine("{0} MiaoObserver.....", this.GetType().Name); if (this._ObserverList != null && this._ObserverList.Count > 0) { foreach (var item in this._ObserverList) { item.Action(); } } } private event Action MiaoHandler; public void MiaoEvent() { Console.WriteLine("{0} MiaoEvent.....", this.GetType().Name); if (this.MiaoHandler != null) { foreach (Action item in this.MiaoHandler.GetInvocationList()) { item.Invoke(); } } } }
這樣在調用的時候,增加一個,減少一個,更改順序,就不要再去修改Cat類了。
Cat cat = new Cat(); cat.AddObserver(new Chicken()); cat.AddObserver(new Baby()); cat.AddObserver(new Brother()); cat.AddObserver(new Dog()); cat.AddObserver(new Father()); cat.AddObserver(new Mother()); cat.AddObserver(new Mouse()); cat.AddObserver(new Neighbor()); cat.AddObserver(new Stealer()); cat.MiaoObserver();