美文网首页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