当前位置:主页 > 查看内容

给女朋友讲设计模式 之 中介者模式

发布时间:2021-07-14 00:00| 位朋友查看

简介:中介者模式 这天我和往常一样,正在电脑前苦苦思索框架设计,她又带着情绪过来了,原因就是因为她想喝奶茶的时候,奶茶涨价了,她就很生气. 虽然和她说过很多次,奶茶其实成本很便宜,最多糖多,因为人一吃糖就会很快乐,所以会让人上瘾.她说对呀,我没有吃到甜的,现在……

中介者模式

这天我和往常一样,正在电脑前苦苦思索框架设计,她又带着情绪过来了,原因就是因为她想喝奶茶的时候,奶茶涨价了,她就很生气.

虽然和她说过很多次,奶茶其实成本很便宜,最多糖多,因为人一吃糖就会很快乐,所以会让人上瘾.她说对呀,我没有吃到甜的,现在感觉很生气.

我不知道说些什么,我说,那这样吧,待会我把代码重构一下,我带你取个好地方,去那里喝奶茶.

她问:"是哪里啊?"

我说:"到了你就知道啦."

她有点不生气了,坐过来问我:"你还要多久啊"

我说:"快了快了,按照中介者模式来重构一下就ok".

"中介者模式?"她问.

"嗯,也是一个设计模式,对代码结构有着优雅的设计"我回答她.

她又问:"那是什么样的呀?"

她的好奇心又被勾起来了,几乎忘了自己要喝奶茶.

她又问:"你总说要优雅优雅,到底什么样子算优雅呀"

我想了想,也是,我也经常说要优雅的调用方法,优雅的设计,那么到底什么样的代码算是优雅呢?

过了一会儿,我说:"总结起来应该是这样,各个功能模块之间的耦合降低,封装方法良好,可扩展性好,这个应该就是一套优雅的代码了".

"听起来很简单呀,我还以为有很多个条条框框呢".她看着我说.

"哈哈,把这个简单的做好就是不简单."我看着她回答.

"这句话我初中的时候经常看."我边说边转过脸去.

我笑了笑,让出点位置,让她可以看到电脑屏幕,接着说:"游戏中会有许多个模块,这些模块之间会有通讯,比如会有战斗模块,成就模块,强化模块,声音模块,UI模块等等."

她的眼睛渐渐有了小星星,我知道,她的兴趣上来了.

我接着说:"那么这些模块之间会有相互调用的问题,不如,战斗的时候要调用声音模块,同样的,点击UI的时候一样要调用声音模块.而强化模块也会调用UI模块等等等等"

"这个你不是说过了吗?模块上层直接调用,与上层耦合性高,用的是外观模式呀,上层直接调用接口啊,不管底层."

我很惊讶的说:"你居然还记得,外观模式"

她说:"对呀,外观模式解耦的.我还记得你拿车举例子."

没想到她还记得.

我说,但是这个不对了哦.它们二者之间确实很像,但是还是有些不同的.你看,像是之前说的外观模式,它是一种结构模式,外观模式对与某个模块提供统一的接口,并且,它是单向的."

听到这里她皱了皱眉头,说:"我没太明白"

我看着她,一脸的困惑

我摸了摸她的头,说:"外观模式可以理解为对外简洁,你看它,用图表示是这样的"

打个比方,游戏开始的时候要初始化,那么用gameRoot中的init方法,初始化各个模块,那么它只需要调用外观模式的接口就可以了,这就是提供统一接口的意思.

"这个我知道啊,那个单向呢?"

"从图上看,只能高级接口调用下面的接口是吧,下面的接口是不能访问上层的"

"就这个意思?"

"是啊"

她看了看我,说:"原来这么简单."

我说对呀,本来编程就不难.

我接着说:"那么中介者模式,把它放在外观模式一起说,来做个对比的话,那么就是:外观模式单向的一对多的情况,负责的是大的模块化的调用,那么中介者模式就是每个模块与每个模块之间的调用.从图上面来说就是":

每个模块之间不直接通讯,而是通过中介脚本来传递消息,那么这样一样,每个模块之间的耦合就降低了.

"哦",她似乎懂了

我接着在代码中给她展示了一下,首先对她说,如果我们现在设计一个比较简单的中介者模式,就有一个UI,一个Game.还有一个充当中介者的GameManager.

UI_Base.cs

public abstract class UI_Base
{
    protected GameManager gameManager = null;
    public UI_Base(GameManager _gameManager)
    {
        gameManager = _gameManager;
    }
    public abstract void RecvMsg(string msg);    
}

Game_Base.cs

public abstract class Game_Base {

    protected GameManager gameManager = null;
    public Game_Base(GameManager _gameManager)
    {
        gameManager = _gameManager;
    }

    public abstract void RecvMsg(string msg);

}

GameManager.cs

public class GameManager : MonoBehaviour
{

}

"咦,为什么这个图标是个齿轮啊?"她说.

她看到了我建GameManager.cs的时候它的图标是个齿轮

我回答她说:"这算是它的一个bug吧,可能它内部也有个同名的脚本".

说实话,其实我也不知道-_-||

"你把这些都弄成抽象方法啦"她已经看到了,本来我还想给她说一下的,不过既然她已经看到了,就直接给她解释吧.

我说:"写成虚方法是因为好写,但是在具体的项目中,还是要写成一般的类,因为UI类和game类比较特殊,用的地方比较多.

"嗯嗯"

我说:"接下来就写一下它们的子类吧."

UILogic.cs

using UnityEngine;

public class UILogic : UI_Base
{
    public UILogic(GameManager gameManager) : base(gameManager)
    { }

    public void SendMsg()
    {
        gameManager.SendMsg(this, "按下攻击按钮了哦,英雄动起来哦");
    }

    public override void RecvMsg(string msg)
    {
        Debug.Log("UILogic接收到信息:" + msg);
    }
}

GameLogic.cs

using UnityEngine;

public class GameLogic : Game_Base
{
    public GameLogic(GameManager gameManager) : base(gameManager)
    { }

    public void SendMsg()
    {
        gameManager.SendMsg(this, "英雄重生了!界面恢复色彩吧");
    }

    public override void RecvMsg(string msg)
    {
        Debug.Log("Gamelogic接收到信息:" + msg);
    }
}

再写好gameManager

GameManager.cs

using UnityEngine;

public class GameManager : MonoBehaviour
{

    UILogic uiLogic = null;
    GameLogic gameLogic = null;

    public void InitUI(UILogic theuILogic)
    {
        uiLogic = theuILogic;
    }
    public void InitGame(GameLogic theGameLogic)
    {
        gameLogic = theGameLogic;
    }

    public void SendMsg(object obj, string msg)
    {
        if (obj == uiLogic)
        {
            gameLogic.RecvMsg(msg);
        }
        if (obj == gameLogic)
        {
            uiLogic.RecvMsg(msg);
        }
    }

    private void Start()
    {
        uiLogic = new UILogic(this);
        gameLogic = new GameLogic(this);
        InitUI(uiLogic);
        InitGame(gameLogic);


        uiLogic.SendMsg();
        gameLogic.SendMsg();
    }

}

"这个不也还是调用嘛".她果然很聪明,一下就说出了本质.

对的,都是代码调用代码.

她接着又说:"这个sendMsg相当于一个封装,而UI部分的Send经过GameManager的中转最后调用到Game的Recv".

我说:"你这么聪明,要不要看看运行结果呀?"

她说:"好呀,那就看看吧"

"还有,"她又想到了啥.GameManager里面的几个实例是不是可以抽离出来,然后再给类继承,变成外观模式啊?"

我愕然,相对于我来说,她已经做的比我好多了.

"你等我一下,我去换衣服"

"换衣服干嘛?"

"出去喝奶茶"

说完,她回自己的房间了,留下我一脸的羡慕,羡慕我自己有个这么聪明的女朋友.


本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文

  • 周排行
  • 月排行
  • 总排行

随机推荐