觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀態發生變化的時,會通知全部觀察者對象,使他們可以自動更新本身。 ide
當一個對象的改變須要同時改變其餘對象的時候,並且不知道有多少對象有待改變時,應該考慮使用觀察者模式。 this
觀察者模式所作的工做其實就是解除耦合,讓耦合的雙方都依賴於抽象,而不是依賴於具體,從而使的各自的變化都不會影響另外一邊的變化。 spa
Subject類:它把全部對觀察者對象的引用保存在一個彙集裏面,每一個主題均可以有任意數量的觀察者,抽象主題提供一個接口,能夠增長和刪除觀察者對象。 orm
public void Notify() server
{ 對象
foreach(Observer o in observers) blog
{ 繼承
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); }
/// <summary> /// 移除觀察者 /// </summary> /// <param name="observer">觀察者</param> public void Detach(Observer observer) { observers.Remove(observer); }
/// <summary> /// 通知觀察者 /// </summary> public void Notify() { foreach (Observer o in observers) { o.Update(); } } } |
2、ConcreteSubject類,具體主題或者具體通知者 |
public class ConcreteSubject:Subject { private string _subjectState;
/// <summary> /// 具體被觀察者狀態 /// </summary> 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> /// 添加觀察者 /// </summary> /// <param name="observer">觀察者</param> 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; } } } |
5、客戶端代碼 |
static void Main(string[] args) { 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(); Console.Read(); } |
觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀態發生變化的時,會通知全部觀察者對象,使他們可以自動更新本身。解決的是「當一個對象的改變須要同時改變其餘對象的時候」問題。
版權
做者:靈動生活
出處:http://www.cnblogs.com/ywqu
若是你認爲此文章有用,請點擊底端的【推薦】讓其餘人也瞭解此文章,
你也能夠加個人新浪微博,以便實時瞭解個人動態:http://weibo.com/ywqu
WOWO英語(英語培訓學校):http://www.wowomandarin.cn 上海電子商務解決方案:http://www.hello36.com
上海閃酷系列解決方案:
電子商務解決方案 移動電商APP軟件 培訓學校管理系統 購物分享社區系統 移動開發解決方案 在線問卷調查系統
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。