观察者模式包含四个角色: (subject)目标又称为主题,它是指被观察的对象; knows its observers. 它知道它的观察者;并提供用于注册与删除的接口 (concreteSubject)具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知; (observer)观察者将对观察目标的改变做出反应; (concreteObserver)具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。
代码示例
/*
*Observer Pattern
*/using System;using System.Collections.Generic;namespace Pattern01
{classProgram{staticvoidMain(string[] args){ConCreteSubject s =newConCreteSubject();Observer observer1 =newConcreteObserver(s,"x");Observer observer2 =newConcreteObserver(s,"y");Observer observer3 =newConcreteObserver(s,"z");
s.Attach(observer1);
s.Attach(observer2);
s.Attach(observer3);// Change subject and notify observers
s.SubjectState ="ABC";
s.Notify();
Console.WriteLine("------------------");
s.Detach(observer1);
s.SubjectState ="edf";
s.Notify();
Console.ReadKey();}}/// <summary>/// knows its observers. Any number of Observer objects may observe a subject/// provides an interface for attaching and detaching Observer objects./// </summary>abstractclassSubject{private List<Observer> _observers =newList<Observer>();publicvoidAttach(Observer observer){
_observers.Add(observer);}publicvoidDetach(Observer observer){
_observers.Remove(observer);}publicvoidNotify(){/依次通知订阅者foreach(Observer o in _observers){
o.Update();}}}/// <summary>/// stores state of interest to ConcreteObserver/// sends a notification to its observers when its state changes/// </summary>classConCreteSubject:Subject{privatestring _subjectState;publicstring SubjectState
{get{return _subjectState;}set{ _subjectState =value;}}}/// <summary>/// defines an updating interface for objects that should be notified of changes in a subject./// </summary>abstractclassObserver{publicabstractvoidUpdate();}/// <summary>/// maintains a reference to a ConcreteSubject object/// stores state that should stay consistent with the subject's/// implements the Observer updating interface to keep its state consistent with the subject's/// </summary>classConcreteObserver:Observer{privatestring _name;privatestring _observerState;privateConCreteSubject _subject;/目标publicConcreteObserver(ConCreteSubject subject,string name){this._subject = subject;this._name =name;}publicoverridevoidUpdate(){
_observerState = _subject.SubjectState;///目标通知内容
Console.WriteLine($"Observer {_name} new state is {_observerState}");}publicConCreteSubject subject
{get{return _subject;}set{ _subject =value;}}}}
代码示例2 下面代码模拟,将IBM股票价格的变化,及时通知到订阅了IBM股票的投资者。
/*
*Observer Pattern
*/using System;using System.Collections.Generic;namespace Pattern01
{classProgram{staticvoidMain(string[] args){IBM ibm =newIBM("IBM",120.00);
ibm.Attach(newInvestor("Sorros"));
ibm.Attach(newInvestor("Berkshire"));IInvestor investor =newInvestor("job-Stone");
ibm.Attach(investor);// 股票价格有变化,则通知订阅股票的投资者
ibm.Price =120.10;
ibm.Price =121.00;
ibm.Price =120.50;
ibm.Price =120.75;
Console.ReadKey();}}/// <summary>/// SUBject-- knows its observers. Any number of Observer objects may observe a subject/// provides an interface for attaching and detaching Observer objects./// </summary>abstractclassStock{privatestring _symbol;privatedouble _price;private List<IInvestor> _invests =newList<IInvestor>();//observerspublicStock(string symbol,double price){
_symbol = symbol;
_price = price;}publicvoidAttach(IInvestor investor){
_invests.Add(investor);}publicvoidDetach(IInvestor investor){
_invests.Remove(investor);}publicvoidNotify(){/依次通知订阅者foreach(IInvestor o in _invests){
o.Update(this);}
Console.WriteLine();}publicdouble Price
{get{return _price;}set{if(_price !=value){
_price =value;//价格有变动则通知订阅者Notify();}}}publicstring Symbol
{get{return _symbol;}}}/// <summary>/// concreteSubject--- stores state of interest to ConcreteObserver/// sends a notification to its observers when its state changes/// </summary>classIBM:Stock{publicIBM(string symbol,double price):base(symbol, price){}}/// <summary>/// Observer-- defines an updating interface for objects that should be notified of changes in a subject./// </summary>interfaceIInvestor{voidUpdate(Stock stock);}/// <summary>/// concreteObserver---maintains a reference to a ConcreteSubject object/// stores state that should stay consistent with the subject's/// implements the Observer updating interface to keep its state consistent with the subject's/// </summary>classInvestor:IInvestor{privatestring name;privateStock _stock;//maintains a reference to a ConcreteSubject object publicInvestor(string name){this.name = name;}publicvoidUpdate(Stock stock){
_stock = stock;
Console.WriteLine($"notify {name} of {_stock.Symbol} change to {_stock.Price}");}}}