模式定义
观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
UML类图
- 观察目标(Subject)
- 具体观察目标(ConcreteSubject)
- 观察者(Observer)
具体观察者(ConcreteObserver)
代码结构
public class ObserverApp { public void Run() { ConcreteSubject s = new ConcreteSubject(); s.Attach(new ConcreteObserver() { Subject = s, Name = "X" }); s.Attach(new ConcreteObserver() { Subject = s, Name = "Y" }); s.Attach(new ConcreteObserver() { Subject = s, Name = "Z" }); s.SubjectState = "ABC"; s.Notify(); } } abstract class Subject { private List<Observer> _observers = new List<Observer>(); public void Attach(Observer observer) { _observers.Add(observer); } public void Detach(Observer observer) { _observers.Remove(observer); } public void Notify() { foreach(Observer o in _observers) { o.Update(); } } } class ConcreteSubject : Subject { public string SubjectState { get; set; } } abstract class Observer { public abstract void Update(); } class ConcreteObserver : Observer { public string Name { get; set; } public ConcreteSubject Subject { get; set; } public override void Update() { string state = this.Subject.SubjectState; Console.WriteLine("Observer {0}‘s new state is {1}",this.Name,state); } }
情景案例
现在大家最关心的应该是回家过年的火车票,相信大家电脑上也安装了些刷票的软件吧!这样才能安心工作,等有票了自动通知。
public class ObserverApp { public void Run() { Ticket360 s = new Ticket360(); s.Attach(new ConcreteCustomer() { Subject = s, Name = "小王" }); s.Attach(new ConcreteCustomer() { Subject = s, Name = "小赵" }); s.Attach(new ConcreteCustomer() { Subject = s, Name = "小孙" }); s.TicketState = "有坐票"; s.Notify(); } } /// <summary> /// 火车票 /// </summary> abstract class Ticket { private List<Customer> _observers = new List<Customer>(); public void Attach(Customer observer) { _observers.Add(observer); } public void Detach(Customer observer) { _observers.Remove(observer); } public void Notify() { foreach (Customer o in _observers) { o.Notify(); } } } class Ticket360 : Ticket { public string TicketState { get; set; } } abstract class Customer { public abstract void Notify(); } class ConcreteCustomer : Customer { public string Name { get; set; } public Ticket360 Subject { get; set; } public override void Notify() { string state = this.Subject.TicketState; Console.WriteLine("{0}顾客关注的火车票现在状态为 {1}", this.Name, state); } }
C#中的优化
在C#中其实可以通过
delegate
和Event
,更方便的实现观察者模式。