首页 > 设计模式 > 初尝Observer 模式

初尝Observer 模式

观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。

意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

结构图

Observer 结构图从具体主题角色指向抽象观察者角色的合成关系,代表具体主题对象可以有任意多个对抽象观察者对象的引用。之所以使用抽象观察者而不是具体观察者,意味着主题对象不需要知道引用了哪些ConcreteObserver类型,而只知道抽象Observer类型。这就使得具体主题对象可以动态地维护一系列的对观察者对象的引用,并在需要的时候调用每一个观察者共有的Update()方法。这种做法叫做”面向接口编程”。

实际上在C#中实现Observer模式没有这么辛苦,.NET中提供了Delegate与Event机制,我们可以利用这种机制简化Observer模式。下面我会用一段代码同时演示2种模式。

代码

using System;
using System.Collections.Generic;

namespace Observer
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("------------------------------");
            Console.WriteLine("使用观察者模式:");
            Email e = new Email();
            Mobole m = new Mobole();

            Microsoft ms = new Microsoft();
            ms.Add(e);
            ms.Add(m);
            ms.Price = 50;
            Console.WriteLine();
            Google g = new Google();
            g.Add(e); g.Add(m);
            g.Price = 220;
            Console.WriteLine("------------------------------");

            Console.WriteLine("使用Event 模式:");
            Google g2 = new Google();
            g2.priceChange += e.Update;
            g2.Price = 300;
            Microsoft m2 = new Microsoft();
            m2.priceChange += m.Update;
            m2.Price = 100;

        }
    }

    public interface IObserver {
        void Update(string symbol,decimal price);
    }

    public delegate void PriceChangeHandler(string symbol,decimal price);
    abstract class Stock {
        private string _symbol;
        private decimal _price;
        protected List list = new List();
        public event PriceChangeHandler priceChange;

        public decimal Price {
            get { return _price; }
            set {
                _price = value;
                this.Notify(this._symbol,this._price);
                this.OnChange(this._symbol, this._price);
            }
        }
        void OnChange(string symbol,decimal price) {
            if (priceChange != null)
                priceChange(symbol,price);
        }

        public Stock(string sysbol,decimal price) {
            this._price = price;
            this._symbol = sysbol;
        }

        public void Add(IObserver ob)  {
            list.Add(ob);
        }
        public void Remove(IObserver ob)  {
            list.Add(ob);
        }
        protected virtual void Notify(string symbol, decimal price)  {
            foreach (IObserver ob in list)
                ob.Update(symbol, price);
        }
    }

    class Microsoft:Stock {
        public Microsoft():base("Microsoft",120) { }
    }
    class Google : Stock {
        public Google() : base("Google", 200) { }
    }

    class Email:IObserver {
        public void Update(string symbol,decimal price) {
            Console.WriteLine("尊敬的客户,您使用Email 订阅了{0} 的股票,它的最新价格为 {1}!",symbol,price);
        }
    }
    class Mobole : IObserver {
        public void Update(string symbol, decimal price) {
            Console.WriteLine("尊敬的客户,您使用Mobile 订阅了{0} 的股票,它的最新价格为 {1}!", symbol, price);
        }
    }

}

运行结果

Observer 运行结果

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.