其中,關鍵的代碼如下:
delegate void UpdateDelegate();
定義一個Delegate,用來規范函數結構。不管是ConcreteObserver類的Update方法還是AnotherObserver類的Show方法都符合該Delegate。這不象用Observer接口來規范必須使用Update方法那麼嚴格。只要符合Delegate所指定的方法結構的方法都可以在後面被事件所處理。
public event UpdateDelegate UpdateHandler;
定義一個事件,一旦觸發,可以調用一組符合UpdateDelegate規范的方法。
public void Attach( UpdateDelegate ud )
{
UpdateHandler += ud;
}
訂閱事件。只要是一個滿足UpdateDelegate的方法,就可以進行訂閱操作(如下所示)。
s.Attach(new UpdateDelegate(o1.Update));
s.Attach(new UpdateDelegate(o2.Update));
s.Attach(new UpdateDelegate(o3.Show));
在Notify方法中:
public void Notify()
{
if(UpdateHandler != null) UpdateHandler();
}
只要UpdateHandler != null(表示有訂閱者),就可以觸發事件(UpdateHandler()),所有的訂閱者便會接到通知。
五、一個實際應用觀察者模式的例子
該例子演示了注冊的投資者在股票市場發生變化時,可以自動得到通知。該例子仍然使用的是傳統的Observer處理手段,至於如何轉換成Delegate與Event留給讀者自己考慮。
// Observer pattern -- Real World example
using System;
using System.Collections;
// "Subject"
abstract class Stock
{
// FIElds
protected string symbol;
protected double price;
private ArrayList investors = new ArrayList();
// Constructor
public Stock( string symbol, double price )
{
this.symbol = symbol;
this.price = price;
}
// Methods
public void Attach( Investor investor )
{
investors.Add( investor );
}
public void Detach( Investor investor )
{
investors.Remove( investor );
}
public void Notify()
{
foreach( Investor i in investors )
i.Update( this );
}
// PropertIEs
public double Price
{
get{ return price; }
set
{
price = value;
Notify();
}
}
public string Symbol
{
get{ return symbol; }
set{ symbol = value; }
}
}
// "ConcreteSubject"
class IBM : Stock
{
// Constructor
public IBM( string symbol, double price )
: base( symbol, price ) {}
}
// "Observer"
interface IInvestor
{
// Methods
void Update( Stock stock );
}
// "ConcreteObserver"
class Investor : IInvestor
{
// FIElds
private string name;
private string observerState;
private Stock stock;
// Constructors
public Investor( string name )
{
this.name = name;
}
// Methods
public void Update( Stock stock )
{
Console.WriteLine( "NotifIEd investor {0} of {1}'s change to {2:C}",
name, stock.Symbol, stock.Price );
}
// PropertIEs
public Stock Stock
{
get{ return stock; }
set{ stock = value; }
}
}
/**//// <summary>
/// ObserverApp test
/// </summary>
public class ObserverApp
{
public static void Main( string[] args )
{
// Create investors
Investor s = new Investor( "Sorros" );
Investor b = new Investor( "Berkshire" );
// Create IBM stock and attach investors
IBM ibm = new IBM( "IBM", 120.00 );
ibm.Attach( s );
ibm.Attach( b );
// Change price, which notifIEs investors
ibm.Price = 120.10;
ibm.Price = 121.00;
ibm.Price = 120.50;
ibm.Price = 120.75;
}
}