观察者模式

 

虽然观察者模式有很多变体,但该模式的基本前提包含两个角色:观察者主体(熟悉 Smalltalk MVC 的人将这些术语分别称为视图和模型)。 在用户界面的环境中,观察者是负责向用户显示数据的对象。 另一方面,主体表示从问题域中模拟的业务抽象。 正如图 1 中所描述的一样,在观察者和主体之间存在逻辑关联。 当主体对象中发生更改时,(例如,修改实例变量),观察者就会观察 这种更改,并相应地更新其显示

Observer ----observes----à Subject

观察者模式的步骤:观察者注册主体,表明它对观察的意向。 在某种状态发生变化时,主体向观察者通知这种变化情况。 当观察者不再希望观察主体时,观察者从主体中撤消注册 这些步骤分别称为观察者注册通知撤消注册

下面是两个接口:

    //interface the all observer classes should implement

    public interface IObserver

    {

        void Notify(object anObject);

    }

 

    //interface that all observable classes should implement

    public interface IObservable

    {

        void Register(IObserver anObserver);

        void UnRegister(IObserver anObserver);

}

 

除了这些接口外,框架还经常为主体提供一个用于扩展的通用基类。 此基类扩展减少了支持观察者模式所需的工作。 基类实现 IObservable 接口,以提供支持观察者实例存储和通知所需的基础结构。

尽管可能任何容器都可以完成这一任务,但该类在 Register UnRegister 方法中将观察者存储委派给哈希表实例(为了方便起见,我们在示例中使用哈希表作为容器,它只使用一个方法调用来撤消注册特定的观察者实例)。还要注意添加了 NotifyObservers 方法。 此方法用于通知哈希表中存储的观察者。 在调用此方法时,将枚举该容器,并对观察者实例调用 通知方法。

//helper class that implements observable interface

    public class ObservableImpl : IObservable

    {

        //container to store the observer instance

        protected Hashtable _observerContainer = new Hashtable();

 

        //add the observer

        public void Register(IObserver anObserver)

        {

            _observerContainer.Add(anObserver, anObserver);

        }

 

        //remove the observer

        public void UnRegister(IObserver anObserver)

        {

            _observerContainer.Remove(anObserver);

        }

 

        //common method to notify all the observers

        public void NotifyObservers(object anObject)

        {

            //enumeration the observers and invoke their notify method

            foreach (IObserver anObserver in _observerContainer.Keys)

            {

                anObserver.Notify(anObject);

            }

        }

}

 

下面是主体类,表示股票,它只有一个属性表示当前的价格,当价格发生变化时,自动的通知观察者:

//represents a stock in an application

    public class Stock : ObservableImpl

    {

        //instance variable for ask price

        object _askPrice;

 

        //property for ask price

        public object AskPrice

        {

            set

            {

                _askPrice = value;

                base.NotifyObservers(_askPrice);

            }

        }

}

下面是观察者,用于向用户显示这个变化:

//represents the user interface in the application

    public class StockDisplay : IObserver

    {

        public void Notify(object anObject)

        {

            Console.WriteLine("The new ask price is:" + anObject);

        }

 

}

最后是启动的测试代码:

   public class MainClass

    {

        public static void Main()

        {

            //create new display and stock instances

            StockDisplay stockDisplay = new StockDisplay();

            Stock stock = new Stock();

 

            //register the grid

            stock.Register(stockDisplay);

 

            //loop 100 times and modify the ask price

            for (int looper = 0; looper < 100; looper++)

            {

                stock.AskPrice = looper;

            }

 

            //unregister the display

            stock.UnRegister(stockDisplay);

 

        }

    }

 

 

 

 

 

posted on 2010-10-22 15:44 cutebear 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/bear831204/archive/2010/10/22/1858395.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值