用心理解设计模式——观察者模式 (Observer Pattern)

前置文章: 设计模式的原则 

其他设计模式:用心理解设计模式

设计模式相关代码已统一放至 我的 Github

 

一、定义

  行为型模式之一。

  Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

  (定义对象间一对多的依赖关系,使得每当一个对象改变状态时,所有依赖于它的对象都会被通知并且自动更新。)

二、结构解析

  观察者模式的一般结构有四种角色: 抽象主题、抽象观察者、具体主题、具体观察者。

  抽象主题(Subject):持有/关联一组观察者,实现添加、移除观察者的方法,并定义一个在数据变化时通知观察者的接口

  抽象观察者(Observer):定义一个收到通知时刷新自身的接口

  具体主题(ConcreteSubject):继承抽象主题,维护一组原有数据,实现通知观察者的接口(可能主动,可能被动)。

  具体观察者(ConcreteObserver):实现收到通知时刷新自身的接口。

三、评价

  观察者模式是一个用于“同步数据/状态”、“通知变化” 的设计模式。

  优点:通知交互依赖于抽象接口,一对多时系统结构仍然清晰。

四、发布订阅模式

  发布订阅模式与观察者模式是有差别的。

  发布订阅模式相比观察者模式新增了一个调度中心,用于集中处理主题与观察者的通知关系(类似中介者,将网状结构捋直为线性结构,如下图)。

  主题不再关心观察者是谁,观察者也不关心触发事件的谁,两者都只与调度中心交互,从而使两者解耦。

  发布订阅模式的实现将在之后写Unity框架的时候给出。

五、实现

  观察者模式的实现

using System.Collections.Generic;
using UnityEngine;

namespace Observer
{
    //抽象主题
    public abstract class Subject
    {
        public List<Observer> observers = new List<Observer>();

        public void Attach(Observer observer)
        {
            observers.Add(observer);
        }

        public void Detach(Observer observer)
        {
            observers.Remove(observer);
        }

        public abstract void Notify();
    }

    //抽象观察者
    public abstract class Observer
    {
        public abstract void Update(string newData);
    }

    //具体主题
    public class ConcreteSubject : Subject
    {
        private string data;
        public ConcreteSubject(string initData)
        {
            this.data = initData;
        }

        //主动通知
        public override void Notify()
        {
            foreach (Observer o in observers)
            {
                o.Update(data);
            }
        }

        //改变数据并通知(被动通知)
        public void ChangeData(string newData)
        {
            if (newData != data)
            {
                data = newData;
                Notify();
            }
        }
    }

    //具体观察者X
    public class ConcreteObserverX : Observer
    {
        public override void Update(string newData)
        {
            Debug.Log("ConcreteObserverX 观察到数据更新:" + newData);
        }
    }

    //具体观察者Y
    public class ConcreteObserverY : Observer
    {
        public override void Update(string newData)
        {
            Debug.Log("ConcreteObserverY 观察到数据更新:" + newData);
        }
    }

    //具体观察者Z
    public class ConcreteObserverZ : Observer
    {
        public override void Update(string newData)
        {
            Debug.Log("ConcreteObserverZ 观察到数据更新:" + newData);
        }
    }

    public class Client
    {
        static public void Main()
        {
            ConcreteSubject subject = new ConcreteSubject("A");

            subject.Attach(new ConcreteObserverX());
            subject.Attach(new ConcreteObserverY());
            subject.Attach(new ConcreteObserverZ());

            //改变状态
            subject.ChangeData("B");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NRatel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值