3-8设计模式之观察者模式(Observer)

3.8.1 模式意图:

在系统中会有一些订阅发布性质的子系统,例如消息系统,用户订阅自己关注的消息,当关注的消息发出时,订阅者也会随之收到相应的推送通知。这也和生活中关注的频道相似,当频道更新时,总会收到对应的推送更新。通过利用订阅发布机制来达到解耦的手段,在设计模式中叫做观察者模式。

3.8.2 模式概念:

它属于行为型模式,定义了一种一对多的依赖关系,让多个观察者监听某一对象。当被监听对象状态发生改变时,会通知所有观察者,使他们能够自动更新自己。

3.8.3 模式元素:

  • 订阅目标抽象(ISubject)
  • 订阅目标细节(ConcreteSubject)
  • 观察者抽象(IObserver)
  • 观察者细节(ConcreteObserver1、ConcreteObserver1)

3.8.4 代码示例:

A.订阅目标抽象

    public interface ISubject
    {
        void NotifyObservers();
        void RegisterObserver(IObserver observer);
        void RemoveObserver(IObserver observer);
    }

B. 订阅目标细节

    public class ConcreteSubject : ISubject
    {
        private IList observerList = new List();
        private string subjectState;
        public void SetState(string State)
        {
            subjectState = State;
            NotifyObservers();
        }
        public void NotifyObservers()
        {
            for (int i = 0; i < observerList.Count; i++)
            {
                observerList[i].Update(subjectState);
            }
        }

        public void RegisterObserver(IObserver observer)
        {
            observerList.Add(observer);
        }

        public void RemoveObserver(IObserver observer)
        {
            observerList.Remove(observer);
        }
    }

C.观察者抽象

    public interface IObserver
    {
        void Update(string state);
    }

D.观察者细节

    public class ConcreteObserver1 : IObserver
    {
        ISubject subject = null;

        public ConcreteObserver1(ISubject subject)
        {
            this.subject = subject;
        }

        public void Update(string state)
        {
            Debug.Log($"{nameof(ConcreteObserver1)}+Update:{state}");
        }
    }

    public class ConcreteObserver2 : IObserver
    {
        ISubject subject = null;

        public ConcreteObserver2(ISubject subject)
        {
            this.subject = subject;
        }

        public void Update(string state)
        {
            Debug.Log($"{nameof(ConcreteObserver2)}+Update:{state}");
        }
    }

示例代码调用

    void Start()
    {
        ConcreteSubject subject = new ConcreteSubject();

        ConcreteObserver1 theObserver1 = new ConcreteObserver1(subject);
        subject.RegisterObserver(theObserver1);
        subject.RegisterObserver(new ConcreteObserver2(subject));

        subject.SetState("发布订阅");
    }

打印日志

3.8.5 写法对比:

3.8.6 模式分析:

观察者模式利用订阅发布机制,当目标自身状态发生改变时,推送信息,而无需知道观察者的数量和执行消息的具体细节。这在系统中是一个非常普遍的解耦手段,例如C#中的委托。
C# 中的委托可以算作观察者模式的简化版,因为只含有对应的行为(函数),而示例中的ConcreteObserver1,既包含行为(Update)也可包含数据,在实际操作中会更灵活一些。

3.8.7 应用场景:

当一个对象发生改变,需要通知一个或多个对象且不需要知道具体接收对象的操作细节。

3.8.8 小结:

观察者模式应用最出名的地方就是MVC模式,通过这种订阅发布机制,使操作以消息的方式发出,而无需关注使用者,降低系统中各子系统或子模块间的耦合度。


更多设计模式详见:设计模式全家桶

发表评论