观察者模式又称“发布/订阅模式”,观察者模式定义了一种一对多依赖关系,让多个观察者对象同时监听某一个主题对象。这个主体对象在状态发生变化时,会通知所有观察者对象,使得它们能够自动更新自己。
解决的问题:将一个系统分割成一个一些相互协作的类会使得,原来类的属性分配到各个协作类中,因此就需要维护这些协作类属性的一致性。我们不希望为了维持一致性而使得各类紧密耦合,这样就会给维护、扩展、重用都带来不便。观察者模式就是解决这类的耦合关系的。
观察者中的角色:1)抽象主题,它把所有观察者对象的引用保存到一个聚集里,每个主体都可以有任何数量的观察者。抽象主题提供一个方法,可以增加和删除观察者对象,同时还提供一个通知各类更行状态的方法。2)具体主题,将有关状态存入具体观察者对象,在具体主题内部改变时,给所有登记过的观察者发出通知。即这里相当于加入了2中提到的分割前的属性。3)抽象观察者,为所有具体观察者提供一个接口(方法),在得到主题通知时更新自己。4)具体观察者,实现抽象观察者角色所要求的更细接口(方法),以便使本身的状态与主题状态协调。
模式优点:观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。从而使得各自的变化都不会影响另一边的变化。
模式缺点:依赖关系并未完全解除,抽象通知者依旧依赖具体的观察者。
适用场景:1)当一个对象的改变需要改变其他对象时,而且它不知道具体有多少个对象有待改变。2)一个抽象模型有两方面,当其中一个方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。
观察者模式结构图:
8.代码
/// <summary> /// 抽象主题类 /// </summary> public abstract class Subject { private IList<Observer> observers= new List<Observer>(); /// <summary> /// 增加观察者 /// </summary> /// <paramname="observer"></param> public void Attach(Observer observer) { observers.Add(observer); } /// <summary> /// 移除观察者 /// </summary> /// <paramname="observer"></param> public void Detach(Observer observer) { observers.Remove(observer); } /// <summary> /// 向观察者(们)发出通知 /// </summary> public void Notify() { foreach (Observer o in observers) { o.Update(); } } } /// <summary> /// 抽象观察者类,为所有具体观察者定义一个接口,在得到通知时更新自己 /// </summary> public abstract class Observer { public abstract void Update(); } /// <summary> /// 具体主题类,定义共享的状态。具体主题角色通常用一个具体子类实现。 /// </summary> public class ConcreteSubject : Subject { private string subjectState; /// <summary> /// 具体观察者的状态 /// </summary> public string SubjectState { get { return subjectState; } set { subjectState = value; } } } /// <summary> /// 具体观察者,实现抽象观察者角色所要求的更新接口,以使本身状态与主题状态相协调 /// </summary> public class ConcreteObserver : Observer { private string observerState; private string name; private ConcreteSubject subject; /// <summary> /// 具体观察者用一个具体主题来实现 /// </summary> public ConcreteSubject Subject { get { return subject; } set { subject = value; } } public ConcreteObserver(ConcreteSubjectsubject, string name) { this.subject = subject; this.name = name; } /// <summary> /// 实现抽象观察者中的更新操作 /// </summary> public override void Update() { observerState =subject.SubjectState; Console.WriteLine("Theobserver's state of {0} is {1}", name, observerState); } }
客户端调用:
classProgram { static void Main(string[] args) { // 具体主题角色通常用具体自来来实现 ConcreteSubject subject = newConcreteSubject(); subject.Attach(newConcreteObserver(subject, "Observer A")); subject.Attach(newConcreteObserver(subject, "Observer B")); subject.Attach(newConcreteObserver(subject, "Observer C")); subject.SubjectState ="Ready"; subject.Notify(); Console.Read(); } }
参考文章:http://www.cnblogs.com/wangjq/archive/2012/07/12/2587966.html