设计模式与实例代码:Observer模式
意图/定义:在对象间定义一种一对多的依赖关系,这样当一个对象的状态改变时,所有依赖者都将和到通知并自动更新问题:当某个事情发生时,需要向一系列变化着的对象发出通知解决方案:观者者将监视某个事件的责任委托给主题对象参与者和协作者:Subject知道自己的Observer,因为Observer会向其注册。主题必须在所监视的事件发生通知观察者效果:如果某些Observer只对事件的一个子
意图/定义:在对象间定义一种一对多的依赖关系,这样当一个对象的状态改变时,所有依赖者都将和到通知并自动更新
问题:当某个事情发生时,需要向一系列变化着的对象发出通知
解决方案:观者者将监视某个事件的责任委托给主题对象
参与者和协作者:Subject知道自己的Observer,因为Observer会向其注册。主题必须在所监视的事件发生通知观察者
效果:如果某些Observer只对事件的一个子集感兴趣,那么Subject可能会告诉它们所不需要知道的事件。如果Subject通知Observer,后者又请求更多信息,则需要进行额外通信。
实现:让某个事件发生需要知道的对象Observer将自己注册到另一个监视事件发生或自己触发事件的Subject对象上。事件发生时,Subject告诉Observer事件已经发生。为了对所有Observer类型的对象实现Obserer接口,有时需要用Adapter模式。
下面是一个在股票变化之后主动通知多个投资人的示例:
using System;
using System.Collections.Generic;
namespace Observer
{
/// <summary>
/// MainApp startup class for Real-World
/// Observer Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Create IBM stock and attach investors
IBM ibm = new IBM("IBM", 120.00);
ibm.Attach(new Investor("Sorros"));
ibm.Attach(new Investor("Berkshire"));
// Fluctuating prices will notify investors
ibm.Price = 120.10;
ibm.Price = 121.00;
ibm.Price = 120.50;
ibm.Price = 120.75;
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Subject' abstract class
/// </summary>
abstract class Stock
{
private string _symbol;
private double _price;
private List<IInvestor> _investors = new List<IInvestor>();
// Constructor
public Stock(string symbol, double price)
{
this._symbol = symbol;
this._price = price;
}
public void Attach(IInvestor investor)
{
_investors.Add(investor);
}
public void Detach(IInvestor investor)
{
_investors.Remove(investor);
}
public void Notify()
{
foreach (IInvestor investor in _investors)
{
investor.Update(this);
}
Console.WriteLine("");
}
// Gets or sets the price
public double Price
{
get { return _price; }
set
{
if (_price != value)
{
_price = value;
Notify();
}
}
}
// Gets the symbol
public string Symbol
{
get { return _symbol; }
}
}
/// <summary>
/// The 'ConcreteSubject' class
/// </summary>
class IBM : Stock
{
// Constructor
public IBM(string symbol, double price)
: base(symbol, price)
{
}
}
/// <summary>
/// The 'Observer' interface
/// </summary>
interface IInvestor
{
void Update(Stock stock);
}
/// <summary>
/// The 'ConcreteObserver' class
/// </summary>
class Investor : IInvestor
{
private string _name;
private Stock _stock;
// Constructor
public Investor(string name)
{
this._name = name;
}
public void Update(Stock stock)
{
Console.WriteLine("Notified {0} of {1}'s " +
"change to {2:C}", _name, stock.Symbol, stock.Price);
}
// Gets or sets the stock
public Stock Stock
{
get { return _stock; }
set { _stock = value; }
}
}
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)