观察者模式
定义
定义对象间的一种一对多的关系,使得当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新
类图
代码

public abstract class Subject { protected IList<Observer> observers = new List<Observer>(); protected int state = 0; public abstract void Notify(); public abstract void Attach(Observer observer); public abstract void Detach(Observer observer); public abstract int GetState(); public abstract void ChangeState(int state); } public class ConcurentSubject : Subject { public override void Attach(Observer observer) { observers.Add(observer); } public override void Detach(Observer observer) { //remove observer from observers } public override void Notify() { foreach (var item in observers) { item.Update(this); } } public override int GetState() { return state; } public override void ChangeState(int state) { this.state = state; } }

public abstract class Observer { public abstract void Update(Subject sub); } public class ConcurentObserver : Observer { public override void Update(Subject sub) { int state = sub.GetState(); Console.WriteLine("new state is {0}", state); } }

public class Client { public static void Do() { Subject subject = new ConcurentSubject(); Observer observer1 = new ConcurentObserver(); Observer observer2 = new ConcurentObserver(); subject.Attach(observer1); subject.Attach(observer2); subject.ChangeState(1); subject.Notify(); subject.ChangeState(2); subject.Notify(); Console.ReadKey(); } }
优点
- 观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
- 观察者模式在观察目标和观察者之间建立一个抽象的耦合
- 观察者模式支持广播通信
- 观察者模式符合“开闭原则”的要求
缺点
- 有很多直接和间接的观察者的话,都通知到会花费很多时间
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化
适用环境
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用
- 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度
- 一个对象必须通知其他对象,而并不知道这些对象是谁
- 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制