定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都获得通知并被自动更新。
简而言之就是,观察者模式能够在被观察者的某个指定动做执行时,通知到其对应的观察者。使得观察者们能够即时作出相应的反应。
示例代码的大概意图其实就是实现一个下载器。当指定文件下载完成后,会通知其观察者们,以便这些观察者能够根据各自需求处理下载下来的文件。c#
接下来,请见具体代码。设计模式
/// <summary> /// 抽象观察者 /// </summary> interface IObserver { void DoUpdate(); }
其实这个抽象观察者,只是一个简单的接口。全部具体观察者都将继承自它。spa
/// <summary> /// 具体观察者-文件下载完成后,备份文件。 /// </summary> class Observer1 : IObserver { public void DoUpdate() { Console.WriteLine("观察者1已将文件备份。"); } } /// <summary> /// 具体观察者-文件下载完成后,压缩文件。 /// </summary> class Observer2 : IObserver { public void DoUpdate() { Console.WriteLine("观察者2已将文件压缩。"); } } /// <summary> /// 具体观察者-文件下载完成后,发送文件。 /// </summary> class Observer3 : IObserver { public void DoUpdate() { Console.WriteLine("观察者3已将文件发送给相关同事。"); } }
以上是三个极简的具体观察者。它们分别在收到下载成功
的通知后,对文件进行备份,压缩及转发。设计
既然观察者们已经准备好了,那么该轮到被观察者了。code
通常,被观察者会相对复杂一点。由于它不仅仅要提供某动做的执行方法,也要提供注册及注销观察者的方法。
当一个被观察者被建立后,首先须要为其绑定一些其必需的观察者(若是须要的话)。观察者们被绑定成功后,这个观察者列表将被被观察者维护着。
若被观察者的某个动做执行完成后,若是须要通知观察者,那么就能够经过这个观察者列表,依次通知到全部须要被通知的观察者。server
/// <summary> /// 文件下载器-被观察者 /// </summary> class Downloader { /// <summary> /// 观察者列表 /// </summary> public readonly HashSet<IObserver> observers; public Downloader() { observers = new HashSet<IObserver>(); } /// <summary> /// 注册观察者 /// </summary> public bool AddObserver(IObserver _observer) { return observers.Add(_observer); } /// <summary> /// 注销观察者 /// </summary> public bool RemoveObserver(IObserver _observer) { return observers.Remove(_observer); } /// <summary> /// 下载 /// </summary> public void Download() { Console.WriteLine("文件开始下载。"); Console.WriteLine("文件下载中···"); Thread.Sleep(3000);// 模拟文件下载的耗时过程 Console.WriteLine("文件下载完成。"); foreach (var observer in observers) { observer.DoUpdate(); } } }
如上代码中,当Download
方法内,文件下载成功后,就会遍历观察者列表,逐个通知对应的观察者,告诉它们:文件下载成功了,你该干吗干吗去
。对象
请看客户端代码blog
// 实例化下载器 var downloader = new Downloader(); // 建立观察者 var o1 = new Observer1(); var o2 = new Observer2(); var o3 = new Observer3(); // 注册观察者 downloader.AddObserver(o1); downloader.AddObserver(o2); downloader.AddObserver(o3); // 下载 downloader.Download();
建立一个被观察者对象,而后为其注册三个观察者。注册成功后,就能够执行下载文件的动做了。
当文件下载完成后,Download
方法内部会自行通知已经成功注册的观察者们。继承
如你所见,当文件下载完成
的通知发出后,各个观察者就开始了它们各自的小动做,分别是备份,压缩,转发。接口
因为观察者们自己就有一个公共的抽象观察者,这样在某个观察者须要变更时,大能够废弃掉这个观察者,另起一个新的观察者,而不用去对现有的任何观察着作任何改动。所以从这个角度上讲,观察者模式是符合开闭原则的。
以上就是极简版的观察者模式的所有内容了。