观察者模式

观察者模式又叫发布-订阅模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

下面举例天气预报通知,演示观察者模式:

首先定义观察者

    /// <summary>
    /// 订阅者接口
    /// </summary>
    public interface IObserver
    {
        //由被观察对象调用的更新方法,拉模式
        void Update(ISubject subject);

        //由被观察对象调用的更新方法,推模式
        void Update(string subjectState);
    }

    /// <summary>
    /// 天气观察者
    /// </summary>
    public class WeatherObserver:IObserver
    {
        //观察者姓名
        public string ObserverName { get; set; }

        #region TObserver 成员
        //得到通知后所作的事情
        public void Update(ISubject subject)
        {
            Console.WriteLine("{0} get weather message:{1}", ObserverName, subject.SubjectState);
        }

        public void Update(string subjectState)
        {
            Console.WriteLine("{0} get weather message:{1}", ObserverName, subjectState);
        }
        #endregion
    }

  

下面定义观察目标对象

    /// <summary>
    /// 观察目标接口
    /// </summary>
    public interface ISubject
    {
        //会改变的内容
        string SubjectState { get; set; }
        //添加观察者
        void Attach(IObserver observer);
       //删除观察者
        void Detach(IObserver observer);

        //拉模式的通知方法定义
        void Notify(ISubject subject);
        //推模式的通知方法定义
        void Notify(string subjectState);
    }


     /// <summary>
    ///提供天气信息的观察目标
    /// </summary>
    public class WeatherSubject:ISubject
    {
        #region TSubject 成员
        //会改变的内容
        private string weather;
        //观察者列表
        private List<IObserver> weatherObservers = new List<IObserver>();

        public string SubjectState
        {
            get
            {
                return weather;
            }
            set
            {
                weather = value;
               //在观察目标变化时通知所有观察者,推模式和拉模式二选一
                this.Notify(this);
                //this.Notify(weather);
            }
        }

        public void Attach(IObserver observer)
        {
            if (!weatherObservers.Contains(observer))
            {
                weatherObservers.Add(observer);
            }
        }

        public void Detach(IObserver observer)
        {
            if (weatherObservers.Contains(observer))
            {
                weatherObservers.Remove(observer);
            }
        }
        
//遍历观察者列表,调用每一个观察者的update方法 public void Notify(ISubject subject) { foreach (IObserver observer in weatherObservers) { observer.Update(subject); } } public void Notify(string subjectState) { foreach (IObserver observer in weatherObservers) { observer.Update(subjectState); } } #endregion }

客户端完成观察者和目标的实例化和绑定

            //定义被观察者
            ISubject weather = new WeatherSubject();

            //定义观察者
            WeatherObserver observer1 = new WeatherObserver();
            observer1.ObserverName = "Kelly";
            WeatherObserver observer2 = new WeatherObserver();
            observer2.ObserverName = "Mike";

            //进行订阅
            weather.Attach(observer1);
            weather.Attach(observer2);

            //更新被观察者状态
            weather.SubjectState = "晴天";
            
            //更新被观察者状态
            weather.SubjectState = "雨天";

  执行结果:     

Kelly get weather message:晴天
Mike get weather message:晴天

Kelly get weather message:雨天
Mike get weather message:雨天

 

将一个系统分割成一系列相互协作的类有一个很不好的副作用,就是需要维护相关对象之间的一致性,我们不希望为了维护一致性而使各类紧密耦合,这样回给维护、扩展和重用带来不便。观察者模式所做的工作就是解耦合,让耦合双方都依赖于抽象,而不依赖与具体,使得各自的变化都不会影响另一边的变化。

当一个对象的改变需要同时改变其他对象,而又不知道具体有多少对象有待改变时,就应该考虑使用观察者模式。

  

 

posted @ 2016-04-20 10:46  angela217  阅读(199)  评论(0编辑  收藏  举报