设计模式-观察者设计模式
一个对象的动作触发多个对象的行为,通过观察者可以去掉对象的依赖,支持各种自定义和扩展。
观察者模式,还要从那只申请的猫开始说起。
猫叫一声之后触发:
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); } }
然后,猫叫一声,触发这些动作:
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); } }
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();