• 设计模式(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/

  • 相关阅读:
    Linux中history执行历史命令方法
    Linux中返回上一次目录
    Linux的vi编辑模式下常用快捷键
    [Android] TextView上同时显示图标和文字
    [Android] macOS的Android Studio快捷键
    [Android] 转-RxJava+MVP+Retrofit+Dagger2+Okhttp大杂烩
    [iOS] 测试设备解决自签名证书问题
    [macOS] keychain的跳坑之旅!git拉取的权限问题
    [PHP] swoole在daemonize模式下,chdir失效问题
    [macOS] macOS下,VirtualBox安装CentOS7.4, 搭建nginx, mysql, PHP5.6&PHP7.1
  • 原文地址:https://www.cnblogs.com/talentzemin/p/9951775.html
Copyright © 2020-2023  润新知