65.9K
CodeProject 正在变化。 阅读更多。
Home

观察者模式

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2008 年 10 月 1 日

CPOL

2分钟阅读

viewsIcon

8757

观察者模式

引言

观察者设计模式定义了一个对象与其依赖项之间的一对多依赖关系。
建立这种依赖关系是为了通知依赖项对象的状态已更改,从而依赖项可以对更改做出反应。

一个很好的例子是博客系统,当博主发布新文章时,订阅者会收到通知。 另一个现实世界的例子是 MVC 架构模式,它使用了这种模式。

观察者模式的使用场景

您应该在以下情况下使用该模式

  • 你有一个发布者/订阅者模型。
  • 对象需要被通知另一个对象的状态变化。
  • 你需要通知状态变化的那个对象不知道它的订阅者是谁。

使用 .NET 内置功能实现观察者模式

请查看这篇非常棒的模式与实践文章 在 .NET 中实现观察者模式

UML 图

C# 示例

以下代码展示了如何实现该模式的示例

    #region Subject
    public abstract class Subject
    {
        #region Members
        private List<IObserver> _observers;
        #endregion

        #region Ctor
        /// <summary>
        /// Construct a new subject object
        /// </summary>
        public Subject()
        {
            _observers = new List<IObserver>();
        }
        #endregion

        #region Methods
        /// <summary>
        /// Attaches a new observer to the subject
        /// </summary>
        /// <param name="observer">The observer to attach</param>
        public void Attach(IObserver observer)
        {
            _observers.Add(observer);
        }

        /// <summary>
        /// Detaches an observer from the subject
        /// </summary>
        /// <param name="observer">The observer to detach</param>

        public void Detach(IObserver observer)
        {
            _observers.Remove(observer);
        }

        /// <summary>
        /// Notify all the observers about the change in the subject's state
        /// </summary>
        public void Notify()
        {
            foreach (IObserver observer in _observers)
            {
                observer.Update();
            }
        }
        #endregion
    }
    #endregion

    #region Concrete Subject
    public class ConcreteSubject<T> : Subject
    {
        #region Properties
        /// <summary>
        /// The state of the subject
        /// </summary>
        public T SubjectState { get; set; }
        #endregion
    }
    #endregion

    #region Observer
    public interface IObserver
    {
        void Update();
    }
    #endregion

    #region Concrete Observer
    public class ConcreteObserver<T> : IObserver
    {
        #region Properties
        /// <summary>
        /// The subject the observer holds
        /// </summary>
        public ConcreteSubject<T> Subject { get; set; }
        private T _observerState;
        #endregion

        #region Ctor
        /// <summary>
        /// Construct a new concrete observer with the given subject
        /// </summary>
        /// <param name="subject">The given subject</param>
        public ConcreteObserver(ConcreteSubject<T> subject)
        {
            Subject = subject;
        }
        #endregion

        #region IObserver Members
        /// <summary>
        /// Make an update to the observer state whenever the
        /// method is called
        /// </summary>
        public void Update()
        {
            _observerState = Subject.SubjectState;

            Console.WriteLine("The new state of the observer:{0}", _observerState.ToString());
        }
        #endregion
    }
    #endregion 

这个例子很容易理解。
我们有一个 IObserver 接口和一个 Subject 抽象类。 观察者通过 Attach 方法注册到主题中,也可以被分离。 主题实现了 Notify 方法,该方法在主题状态更改时通知每个观察者。
当状态改变时,观察者会进行更新,这是 IObserver 接口的主要方法。

以下代码是一个在控制台应用程序中运行该模式的示例场景

   ConcreteSubject<string> subject = new ConcreteSubject<string>();

   subject.Attach(new ConcreteObserver<string>(subject));
   subject.Attach(new ConcreteObserver<string>(subject));
   subject.SubjectState = "Hello World";

   subject.Notify();

   Console.Read(); 

摘要

总而言之,观察者模式被广泛使用,并且非常有用。
例如,你可以在 MVC 框架中或在 Microsoft 博客订阅博客以接收新博主文章通知时看到该模式的使用。 设计模式系列中的下一篇文章将是最后一篇模式文章,它将包括解释器模式。

© . All rights reserved.