设计模式(18)观察者模式
模式介绍
观察者模式试图允许对象在其内部状态改变时通知观察者。
这意味着单个对象需要知道观察它的对象,并且当状态发生变化的时候,需要能够与那些观察者通信。此外,观察者应该被自动通知。
示例
设想我们需要一个系统来建模本地蔬菜市场中蔬菜价格的波动。
我们需要允许餐馆查看价格,并在特定蔬菜的价格低于指定阈值时下订单,这对于每个餐馆来说都是不同的。
抽象的蔬菜类:
/// <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/