觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀态發生變化的時,會通知所有觀察者對象,使他們能夠自動更新自己。
當一個對象的改變需要同時改變其他對象的時候,而且不知道有多少對象有待改變時,應該考慮使用觀察者模式。
觀察者模式所做的工作其實就是解除耦合,讓耦合的雙方都依賴于抽象,而不是依賴于具體,進而使的各自的變化都不會影響另一邊的變化。

public void Notify()
{
foreach(Observer o in observers)
{
o.Update();
}
ConcreteSubject類: 具體的主題,将有關狀态存入具體觀察者對象,在具體主題的内部狀态改變時,給所有登記國的觀察者發出通知。
Observer類:抽象觀察者,為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己
ConcreteObserver:具體觀察者,實作抽象觀察者角色所要求的更新接口,以便使本身的狀态與主題的狀态相協調
1、Subject類,主題或者抽象通知者
public abstract class Subject
private IList<Observer> observers = new List<Observer>();
/// <summary>
/// 添加觀察者
/// </summary>
/// <param name="observer">觀察者</param>
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();
}
}
2、ConcreteSubject類,具體主題或者具體通知者
public class ConcreteSubject:Subject
private string _subjectState;
/// 具體被觀察者狀态
public string SubjectState
get { return _subjectState; }
set { _subjectState = value; }
3、Observer抽象觀察者,為所有的具體觀察者定義一個接口
public abstract class Observer
public abstract void Update();
4、ConcreteObserver具體觀察者
/// <summary>
/// 具體觀察者,實作抽象觀察者角色所要求的更新接口
/// 以便使本身的狀态與主題的狀态相協調
/// </summary>
public class ConcreteObserver:Observer
private string name;
private string observerState;
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()
observerState = subject.SubjectState;
Console.WriteLine("觀察者{0}的新狀态是{1}",name,observerState);
5、用戶端代碼
static void Main(string[] args)
ConcreteSubject cs = new ConcreteSubject();
cs.Attach(new ConcreteObserver(cs,"James"));
cs.Attach(new ConcreteObserver(cs,"Jane"));
cs.SubjectState="OK";
cs.Notify();
Console.Read();
假設有一股票開盤價格16.50元,自從上市以來價格是不斷下降,而且以1.00元的速度下降。
在股票降到12.00元時,股民靈動生活買入了股票。
在股票降到8.05元時,股民Jane買了股票。
Stock類,抽象通知者
定義了委托PriceChangedHandler ,調用了事件參數StockDetailsArgs 。
聲明了事件PriceChanged.
股票在下跌的過程中調用方法OnPriceChanged ,通過此方法觸發事件PriceChanged 。
AttachEvent 方法用來添加觀察者到對象。
StockDetailArgs類,事件參數繼承于EventArgs類,有樹形CurrentPrice用來專遞價格資料
接口IObserver和具體觀察者Observer類:
Stoc_PriceChanged方法:當股票在以1.00元降價的過程中調用此方法。當價格降到符合購買者價格,而且股票沒有被其他人購買的情況時,執行購買行為。
開盤價格:16.50
收盤價格:5.50
當價格降到12.00時,觀察者靈動生活買入此股票
當價格降到8.05時,觀察者Jane買入此股票
1、Stock股票類
public class Stock
private double _openPrice;
private double _closePrice;
public delegate void PriceChangedHandler(object sender, StockDetailArgs e);
public event PriceChangedHandler PriceChanged;
public double OpenPrice
get { return _openPrice; }
set { _openPrice = value; }
public double ClosePrice
get { return _closePrice; }
set { _closePrice = value; }
public void StartTrading()
double current;
//Current price decrements by $1.00 as the stock is traded
current = OpenPrice;
while (current > ClosePrice)
//Stock is falling in increments of $1.00
current = current - 1.00;
//Call the method to raise the event
OnPriceChanged(current);
//Simulate a delay of 2000ms between market price updates
System.Threading.Thread.Sleep(2000);
protected void OnPriceChanged(double currentMarketPrice)
//Any handlers attached to this event?
if (PriceChanged != null)
StockDetailArgs args = new StockDetailArgs();
args.CurrentPrice = currentMarketPrice;
Console.WriteLine("目前股票價格是:" + args.CurrentPrice.ToString());
////Raise the event
PriceChanged(this, args);
/// </summary>
public void AttachEvent(IObserver observer)
PriceChanged += new PriceChangedHandler(observer.Stoc_PriceChanged);
2、事件參數StockDetailArgs
public class StockDetailArgs: EventArgs
private double _currentPrice;
public double CurrentPrice
get { return _currentPrice; }
set { _currentPrice = value; }
3、觀察者接口IObserver
public interface IObserver
void Stoc_PriceChanged(object sender, StockDetailArgs e);
4、具體觀察者Observer
public class Observer : IObserver
private string _investorName;
private double _buyPrice;
private Stock _stoc;
private bool _hasBoughtStock = false;
public string InvestorName
get { return _investorName; }
set { _investorName = value; }
public double BuyPrice
get { return _buyPrice; }
set { _buyPrice = value; }
public Stock Stoc
get { return _stoc; }
set { _stoc = value; }
public Observer(string investorName, double buyPrice)
this.InvestorName = investorName;
this.BuyPrice = buyPrice;
public void Stoc_PriceChanged(object sender, StockDetailArgs e)
if (e.CurrentPrice <= BuyPrice && _hasBoughtStock == false)
Console.WriteLine(string.Format("{0}在價格Price ={1}時買進了股票。",InvestorName,e.CurrentPrice));
_hasBoughtStock = true;
Stock stock = new Stock();
stock.OpenPrice = 16.50;
stock.ClosePrice = 5.50;
Observer james = new Observer("靈動生活", 12.00);
Observer jane = new Observer("jane",8.05);
stock.AttachEvent(james);
stock.AttachEvent(jane);
stock.StartTrading();
觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀态發生變化的時,會通知所有觀察者對象,使他們能夠自動更新自己。解決的是“當一個對象的改變需要同時改變其他對象的時候”問題。
版權
作者:靈動生活 郝憲玮
如果你認為此文章有用,請點選底端的【推薦】讓其他人也了解此文章,
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。