設計模式(18)觀察者模式
阿新 • • 發佈:2018-11-13
模式介紹
觀察者模式試圖允許物件在其內部狀態改變時通知觀察者。
這意味著單個物件需要知道觀察它的物件,並且當狀態發生變化的時候,需要能夠與那些觀察者通訊。此外,觀察者應該被自動通知。
示例
設想我們需要一個系統來建模本地蔬菜市場中蔬菜價格的波動。
我們需要允許餐館檢視價格,並在特定蔬菜的價格低於指定閾值時下訂單,這對於每個餐館來說都是不同的。
抽象的蔬菜類:
/// <summary> /// The Subject abstract class /// </summary> abstract class Veggies { private double _pricePerPound; private List<IRestaurant> _restaurants = new List<IRestaurant>(); public Veggies(double pricePerPound) { _pricePerPound = pricePerPound; } public void Attach(IRestaurant restaurant) { _restaurants.Add(restaurant); } public void Detach(IRestaurant restaurant) { _restaurants.Remove(restaurant); } public void Notify() { foreach (IRestaurant restaurant in _restaurants) { restaurant.Update(this); } Console.WriteLine(""); } public double PricePerPound { get { return _pricePerPound; } set { if (_pricePerPound != value) { _pricePerPound = value; Notify(); //Automatically notify our observers of price changes } } } }
具體的蔬菜類-胡蘿蔔:
/// <summary>
/// The ConcreteSubject class
/// </summary>
class Carrots : Veggies
{
public Carrots(double price) : base(price) { }
}
抽象的餐館:
/// <summary>
/// The Observer interface
/// </summary>
interface IRestaurant
{
void Update(Veggies veggies);
}
具體的餐館:
/// <summary> /// The ConcreteObserver class /// </summary> class Restaurant : IRestaurant { private string _name; private Veggies _veggie; private double _purchaseThreshold; public Restaurant(string name, double purchaseThreshold) { _name = name; _purchaseThreshold = purchaseThreshold; } public void Update(Veggies veggie) { Console.WriteLine("Notified {0} of {1}'s " + " price change to {2:C} per pound.", _name, veggie.GetType().Name, veggie.PricePerPound); if(veggie.PricePerPound < _purchaseThreshold) { Console.WriteLine(_name + " wants to buy some " + veggie.GetType().Name + "!"); } } }
客戶端呼叫:
static void Main(string[] args) { // Create price watch for Carrots and attach restaurants that buy carrots from suppliers. Carrots carrots = new Carrots(0.82); carrots.Attach(new Restaurant("Mackay's", 0.77)); carrots.Attach(new Restaurant("Johnny's Sports Bar", 0.74)); carrots.Attach(new Restaurant("Salad Kingdom", 0.75)); // Fluctuating carrot prices will notify subscribing restaurants. carrots.PricePerPound = 0.79; carrots.PricePerPound = 0.76; carrots.PricePerPound = 0.74; carrots.PricePerPound = 0.81; Console.ReadKey(); }
總結
觀察者模式是常用的設計模式之一,簡單來說就是,如果主體改變了,觀察者需要知道它。
原始碼
https://github.com/exceptionnotfound/DesignPatterns/tree/master/Observer
原文
https://www.exceptionnotfound.net/the-daily-design-pattern-observer/