美文网首页Unity Come On
Unity【话大】设计模式之中介者模式

Unity【话大】设计模式之中介者模式

作者: su9257_海澜 | 来源:发表于2018-12-02 21:45 被阅读387次

我大海澜又回来啦!!!

前言:笔者裸辞玩了2个多月,然后伴随着限制版号的重磅新闻开始找工作,说实话作为菜鸟这个时段还是不怎么好找工作的,比较虐心,不过好事多磨,最终还是拿到了心仪的Offer。笔者又可以开始静心写博客啦。

在此 海澜 非常感谢求职这段时间现实和网上朋友的帮助,正是你们帮助让海澜再次切身体会到互联网精神的温暖,谢谢,谢谢大家~~~


在网上经常说的设计模式有23种,也有一些更多的设计模式,无非也是从这些设计模式中变种而来。如果让笔者来形容什么是设计模式,我认为设计模式是:一种思想,一种模式,一种套路,一种解决问题的高效策略



有说的不正确或者不准确的地方欢迎留言指正


有什么有趣的写作技巧或者想法欢迎大家给我留言,大家的帮助是我写下去最有效的动力



邮件物品在生活我们会经常使用,从一个地点邮寄到另一个地点,就像下图这样,随着这地点的增多,地点与地点关系会变得越来越错综负责,最终会造成牵一发而动全身的效果。

为了降低这种错综复杂的关系,就出现了中转站,如下图所示,这种结构的应用在我们的设计模式中也有对应的映射,那就是我们今天要讲的 中介者模式

下面我们就用这个示例以代码的形式进行展示

中转站

    public enum Country
    {
        China,
        Other
    }
    public abstract class BaseMediator
    {
        protected Country tagCountry;
        protected List<BaseCity> baseCityList = new List<BaseCity>();

        public BaseMediator(Country country)
        {
            tagCountry = country;
        }

        public void AddCity(BaseCity baseBaseCity)
        {
            this.baseCityList.Add(baseBaseCity);
        }

        public abstract void SendMessage(string message, BaseCity baseCityFrom);

    }

    public class ChinaMediator : BaseMediator
    {
        public ChinaMediator(Country country) : base(country) { }

        public override void SendMessage(string message, BaseCity baseCityFrom)
        {
            this.Log($"{baseCityFrom.cityName}发送了一个邮件");

            foreach (var item in this.baseCityList)
            {
                if (item.country == Country.China)
                {
                    if (item != baseCityFrom)
                    {
                        item.GetMessage(message, baseCityFrom);
                    }
                }
                else
                {
                    this.Log($"{baseCityFrom.country}:Say Hello");
                }
            }
        }
    }

城市

public abstract class BaseCity
    {

        public string cityName { get; set; }

        public Country country;

        protected BaseMediator baseMediator;

        public BaseCity(BaseMediator tempBaseMediator)
        {
            baseMediator = tempBaseMediator;
            baseMediator.AddCity(this);
        }

        public virtual void SendMessage(string message)
        {
            baseMediator.SendMessage(message, this);
        }

        public abstract void GetMessage(string message, BaseCity baseCityFrom);
    }

    public class Haerbin : BaseCity
    {
        public Haerbin(BaseMediator tempBaseMediator) : base(tempBaseMediator) { }
        public override void GetMessage(string message, BaseCity baseCityFrom)
        {
            this.Log($"获取{baseCityFrom.cityName}的信息。信息内容为{message}");
        }

        public override void SendMessage(string message)
        {
            baseMediator.SendMessage(message, this);
        }
    }

    public class ShangHai : BaseCity
    {
        public ShangHai(BaseMediator tempBaseMediator) : base(tempBaseMediator) { }

        public override void GetMessage(string message, BaseCity baseCityFrom)
        {
            this.Log($"获取{baseCityFrom.cityName}的信息。信息内容为{message}");
        }

    }

    public class ShenZhen : BaseCity
    {
        public ShenZhen(BaseMediator tempBaseMediator) : base(tempBaseMediator) { }
        public override void GetMessage(string message, BaseCity baseCityFrom)
        {
            this.Log($"获取{baseCityFrom.cityName}的信息。信息内容为{message}");
        }
    }

    public class TaiWan : BaseCity
    {
        public TaiWan(BaseMediator tempBaseMediator) : base(tempBaseMediator) { }

        public override void GetMessage(string message, BaseCity baseCityFrom)
        {
            this.Log($"获取{baseCityFrom.cityName}的信息。信息内容为{message}");
        }

    }
    public class USA : BaseCity
    {
        public USA(BaseMediator tempBaseMediator) : base(tempBaseMediator) { }

        public override void GetMessage(string message, BaseCity baseCityFrom)
        {
            this.Log($"获取{baseCityFrom.cityName}的信息。信息内容为{message}");
        }

    }

调用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MediatorMediatorPattern;
public class MediatorPatternComponent : MonoBehaviour
{

    void Start()
    {
        BaseMediator baseMediator = new ChinaMediator(Country.China);

        Haerbin haerbin = new Haerbin(baseMediator) { cityName = "哈尔滨", country = Country.China };
        ShangHai shangHai = new ShangHai(baseMediator) { cityName = "上海", country = Country.China };
        ShenZhen shenZhen = new ShenZhen(baseMediator) { cityName = "深圳", country = Country.China };
        TaiWan taiWan = new TaiWan(baseMediator) { cityName = "台湾", country = Country.China };
        USA usa = new USA(baseMediator) { cityName = "USA", country = Country.Other };

        taiWan.SendMessage("内陆的朋友你们好");
    }

}

打印结果

现在我们来细看示例代码,经过中介者的处理,我们只需要调用SendMessage函数就可以,完全不需要知道其他的城市的信息,得到到了很好的解耦,也符合迪米特法则,我们可以定义不同的Mediator来持有City列表信息来实现不同的转发规则,让消息的转发更灵活。

中介者模式(Mediator):用一个中介对象老封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互。

中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了多对多交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理。简而言之在需求不明确或者变更频繁时尽量少用中介者模式。为什么会这么说,在下面提到中介者的缺点时会指出。

优点:

  • 降低了类的复杂度,将一对多转化成了一对一
  • 各个类之间的解耦
  • 符合迪米特原则

缺点:

  • 中介者会庞大,变得复杂难以维护

如果遇到下面的场景可以考虑使用中介者

  • 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象
  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

扩展

在示例中我们我可以看到,每一个City都持有一个Mediator,且Mediator中定义了不同的TagCountry,如果我们把TagCountry换成一个省份的List呢?那我们是不是可以根据不同的省份信息来接受不同城市的信息呢?答案当然是可以。

随着不同Mediator越来越多,我们是不是也可以把不同Mediator加入List里面,在放信息的时候便利List<Mediator>发送信息呢?

这时有出现了新的问题,如果不同Mediator中含有相同的TagCountry我们有没有什么改进的方法呢???

这时我们就可以吧TagCountry提取出来,根据不同TagCountry来触发不同Mediator,其实这种实现方式就是大名鼎鼎的MVC消息传递的前身
当然整个MVC的消息传递涉及了:中介者、命令、观察者、门面、单例五种设计模式

PureMVC源码片段

不知道大家有没有Get到Mediator呢?

相关文章

网友评论

    本文标题:Unity【话大】设计模式之中介者模式

    本文链接:https://www.haomeiwen.com/subject/yqelcqtx.html