设计模式 观察者模式
一、概述
观察者模式(Observer Pattern)是设计模式中行为模式的一种,它解决了具有一对多依赖关系的对象的重用问题。此模式的参与者分为两大类,一类是被观察的目标(Target),另一类是观察该目标的观察者(Observer)们。正因为该模式是基于“一对多”的关系,所以该模式一般是应用于由一个目标对象和N个观察者对象组成(当然也可以扩展为有多个目标对象,但我们现在只讨论前者)的场合。当目标对象的状态发生改变或做出某种行为时,正在观察该目标对象的观察者们将自动地、连锁地作出相应的响应行为。
二、原理
我们可以把观察目标理解为主动方、发布方、主体等;把观察者理解为被动方、订阅方、观察器等。目标是整个行为链的源头,其它观察者都依赖于它的变化而作出响应。为了实现低耦合,我们不能使用“直接调用”的方式而需要利用“订阅(清单)-通知”的机制去完成设计。通俗地说就是观察者向目标“订阅”它的改变,而目标发生改变后就“通知”所有已经“订阅”了它的改变的观察者,从而执行“订阅”的内容。这种机制的好处在于降低耦合度,分工明确,目标只负责在自身状态发生改变或做出某种行为时向自身的订阅清单发出“通知”,而不是直接调用观察者的行为(方法);观察者只负责向目标“订阅”它的变化,以及定义自身在收到目标“通知”后所需要做出的具体行为(也就是订阅的内容)。就像我们向出版社订阅报刊一样,出版社有新一期报刊发行时并不是直接跟每位订阅者联系,而是“通知”订阅者名单按顺序给每位订阅者发送所订报刊。
三、示例
题目:猫叫,宝宝哭了,主人醒了
解决方案:
接口声明
using System; namespace Observer { /// <summary> /// 委托:观察者模式的基础,目标具有触发某种事件的能力,相应的观察者应该能处理这种事件 /// </summary> /// <param name="objSender">被观察者</param> /// <param name="objValue">事件的具体内容</param> public delegate void SomethingHappen(ITarget objSender, object objValue); /// <summary> /// 接口:观察者 /// </summary> public interface IObserver { /// <summary> /// 处理目标触发的事件 /// </summary> void DealSomethingHappened(ITarget sender, object objValue); /// <summary> /// 观察指定的目标 /// </summary> void ObserveTarget(ITarget target); /// <summary> /// 取消对特定目标的观察 /// </summary> void UnObserveTarget(ITarget target); } /// <summary> /// 接口:目标 /// </summary> public interface ITarget { /// <summary> /// 目标触发事件 /// </summary> void DoSomething(object objValue); /// <summary> /// 目标触发的事件 /// </summary> event SomethingHappen SomethingHappened; } }
观察者基类
using System; namespace Observer { /// <summary> /// 抽象类:观察者基类,chenxiang,20141122 /// </summary> public abstract class CObserverBase:IObserver { public CObserverBase(){} public abstract void DealSomethingHappened(ITarget sender, object objValue); public void ObserveTarget(ITarget target) { target.SomethingHappened += DealSomethingHappened; } public void UnObserveTarget(ITarget target) { target.SomethingHappened -= DealSomethingHappened; } } }
被观察者基类
using System; namespace Observer { /// <summary> /// 抽象类:目标基类,chenxiang,20141122 /// </summary> public abstract class CTargetBase:ITarget { public CTargetBase() { } public event SomethingHappen SomethingHappened; public virtual void DoSomething(object objValue) { if (SomethingHappened != null) { //通知观察者 SomethingHappened(this, objValue); } } } }
类:Cat,People,Baby
using System; namespace Observer { public class Cat:CTargetBase { public Cat(string strName) { Name = strName; } /// <summary> /// 小猫的名字 /// </summary> public string Name { get; private set; } public override void DoSomething(object objValue) { System.Diagnostics.Debug.WriteLine(Name + " say miao~ miao~"); base.DoSomething(objValue); } } /// <summary> /// 类:People测试观察者模式,chenxiang,20141122 /// </summary> public class People : CObserverBase { public string Name { private set; get; } public People(string strName) { Name = strName; } public override void DealSomethingHappened(ITarget sender, object objValue) { System.Diagnostics.Debug.WriteLine(Name + " Say Shit!"); } } public class Baby : CObserverBase { public string Name { private set; get; } public Baby(string strName) { Name = strName; } public override void DealSomethingHappened(ITarget sender, object objValue) { System.Diagnostics.Debug.WriteLine(Name + " is crying"); } } }
测试代码
Cat catTom = new Cat("Tom");//实例化对象
Baby babyLili = new Baby("Lili");//实例化对象
People peopleJim = new People("Jim");//实例化对象
babyLili.ObserveTarget(catTom);//Lili观察Tom
peopleJim.ObserveTarget(catTom);//Jim观察Tom
catTom.DoSomething(null);//Tom DoSomething
peopleJim.UnObserveTarget(catTom);//jim不再观察Tom
catTom.DoSomething(null);//Tom DoSomething
输出
Tom say miao~ miao~ Lili is crying Jim Say Shit! Tom say miao~ miao~ Lili is crying