设计模式之观察者模式
一:什么事观察者模式?
有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
二:角色?
1) 抽象目标角色(Subject):目标角色知道它的观察者,可以有任意多个观察者观察同一个目标。并且提供注册和删除观察者对象的接口。目标角色往往由抽象类或者接口来实现。
2) 抽象观察者角色(Observer):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。抽象观察者角色主要由抽象类或者接口来实现。
3) 具体目标角色(Concrete Subject):将有关状态存入各个Concrete Observer对象。当它的状态发生改变时, 向它的各个观察者发出通知。
4) 具体观察者角色(Concrete Observer):存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。在本角色内也可以维护一个指向Concrete Subject对象的引用。
三:结构图
四:观察者模式代码
//抽象主题类,抽象主题提供一个接口,可以增加和删除观察者对象。 public abstract class Subject { private List<Observer_u> observer=new List<Observer_u>(); //添加观察者 public void Attach(Observer_u obser) { observer.Add(obser); } //移除观察者 public void Detach(Observer_u obser) { observer.Remove(obser); } //向观察者(们)发出通知 public void Notify() { foreach (var ob in observer) { ob.Update(); } } }
//抽象观察者类,便于在得到通知时修改自己 public abstract class Observer_u { public abstract void Update(); }
//具体观察者或具体通知者,将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。 public class ConcreteSubject:Subject { //具体观察者的状态 private string concreteSate; public string ConcreteSate { get { return concreteSate; } set { concreteSate = value; } } }
//具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。 public class ConcreteObserver : Observer_u { private string state; private string name; private ConcreteSubject subject; //具体观察者用一个具体主题来实现 public ConcreteSubject Subject { get { return subject; } set { subject = value; } } public ConcreteObserver(ConcreteSubject subject, string name) { this.subject = subject; this.name = name; } //实现抽象观察者中的更新操作 public override void Update() { state = subject.ConcreteSate; Console.WriteLine("都有{0}一起出去看电影{1}",name,state); } }
class Program { static void Main(string[] args) { ConcreteSubject sub=new ConcreteSubject(); sub.Attach(new ConcreteObserver(sub,"小明")); sub.Attach(new ConcreteObserver(sub, "小灰")); sub.Attach(new ConcreteObserver(sub, "小刚")); sub.ConcreteSate = "看电影"; sub.Notify(); Console.Read(); } }