看了一些其他人写的,一下就晕了,还是自己写一个给自己看吧。
用event语法糖实现的观察者,与普通的实现,最大的区别在于,Subject的操作中不会直接触发Observer的Update,而是通过event间接实现。
特别注意,标准的观察者模式中,Subject需要Attach所需的Observer,然后执行通知时,依次调用Observer的方法,而用event时,就是将Subject的event绑定所有要调用的Observer的行为,执行时,调用event即可。
1.最直接的版本如下。定义Subject的Notify,里面触发事件,事件调用绑定的Observer的方法。而绑定操作放到场景类的Main中实现。(ObserverA为子类,略了。)
public class Subject { public delegate void Notice(); public event Notice NoticeEvent; public void Notify() { Console.WriteLine("发送通知"); if (NoticeEvent != null) NoticeEvent(); } }
public class Observer { public virtual void Update() { Console.WriteLine("得到通知"); } }
class Program { static void Main(string[] args) { var subject = new Subject(); var observer = new Observer(); var observerA = new ObserverA(); subject.NoticeEvent += new Subject.Notice(observer.Update); subject.NoticeEvent += new Subject.Notice(observerA.Update); subject.Notify(); } }
2.进一步的设计,可以不暴露Observer的Update方法,通过一个包装的Bind方法来绑定二者。如下:
public class Subject { public delegate void Notice(); public event Notice NoticeEvent; public void Notify() { Console.WriteLine("发送通知"); if (NoticeEvent != null) NoticeEvent(); } }
public class Observer { public void Bind(Subject subject) { subject.NoticeEvent += new Subject.Notice(Update); } protected virtual void Update() { Console.WriteLine("得到通知"); } }
class Program { static void Main(string[] args) { var subject = new Subject(); var observer = new Observer(); var observerA = new ObserverA(); observer.Bind(subject); observerA.Bind(subject); subject.Notify(); } }
3.如果考虑与以前的观察者模式的Attach方法一致,还可以在Subject中设计Attach方法,封装调用Observer的Bind,没有实际意义,只是保持接口一致。