风动破

导航

设计模式之观察者Observer

 参考:http://www.cnblogs.com/saville/archive/2012/08/15/2640323.html

 一、概述
在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知。如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化。使用观察者模式可以降低对象之间的依赖,以松耦合的方式实现这一目标。
二、观察者模式
观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。

 

Subject知道它的所有观察者并提供了观察者注册和删除订阅的接口。
Observer为那些在目标发生改变时需获得通知的对象定义一个更新接口。
ConcreteSubject实现Subject接口,当改变状态时向依赖于它的ConcreteObserver发送通知。
ConcreteObserver实现Observer的更新接口,使得自身能根据ConcreteSubject状态的不同而做出相应的改变。
观察者模式分为推模式和拉模式两种。推模式是当有通知时,把依赖对象的信息以参数的形式传递给所有观察者,而拉模式通知方法本身并不带任何的参数,是由观察者自己到依赖对象那里取回相关信息。在推模式下,所有观察者都通过参数传递的方式得到依赖对象的全部信息,与依赖对象之间的耦合较低,但不能实现“按需所取”所需要信息的。而拉模式仅仅是通知观察者,至于要不要提取依赖对象的信息则是观察者自己的事情,这么一来就实现“按需所取”,但往往要在ConcreteObserver里保存一个ConcreteSubject的引用,与ConcreteSubject的耦合也加强了。
观察者模式的Subject一般需要提供观察者注册和删除订阅的接口,但在.NET中,往往可以利用事件和委托的特性来实现观察者模式,这是一种更为优雅的方案。


 

如果网上商店中商品在名称 价格等方面有变化,如果系统能自动通知会员,将是网上商店区别传统商店的一大特色.

这就需要在商品product中加入Observer这样角色,以便product细节发生变化时,

Observer能自动观察到这种变化,并能进行及时的update或notify动作.

 

================================================== 

public class ObserverMode

    {
        public ObserverMode(){
            CreditCart cc = new CreditCart();
            MyAccount account = new MyAccount(1000);
            SMSNotify sms = new SMSNotify();
            cc.SpendMoney += account.Update;
            cc.SpendMoney += sms.Update;
            cc.Money-= 100;
        }
    }
    /// <summary>
    /// 信用卡类
    /// </summary>
    public class CreditCart :EventArgs
    {
        private int money;
        public int Money
        {
            get { return money; }
            set { money = value;
            notify();
            }
        }
        private void notify()
        {
            if (SpendMoney != null)
                SpendMoney(this, this);
        }
        public event EventHandler<CreditCart> SpendMoney;        
    }
    /// <summary>
    /// 观察者泛型
    /// </summary>
    public interface IOserver<T> {
        void Update(object obj, T t);
    }
    /// <summary>
    /// 短信接口
    /// </summary>
    public class SMSNotify : IOserver<CreditCart> 
    {
        /// <summary>
        /// 短信发送
        /// </summary>
        public void Update(object obj, CreditCart t)
        {
            Console.WriteLine("SMS SEND:"+t.Money);
        }
    }
    /// <summary>
    /// 账号接口
    /// </summary>
    public class MyAccount : IOserver<CreditCart> 
    {
        private float _accountAmount;
        public MyAccount(float _accountAmount) { this._accountAmount = _accountAmount; }
        /// <summary>
        /// 账户
        /// </summary>
        public void Update(object obj, CreditCart t)
        {
            _accountAmount += t.Money;
            Console.WriteLine("account amount is {0}",_accountAmount);
        }
    }

posted on 2015-04-30 14:29  风动破  阅读(184)  评论(0)    收藏  举报