iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0

仲介者模式(Mediator)在GoF中的說明是:
「定義一個介面用來包裝一群物件的互動行為。仲介者藉由移除物件間的引用,來減少它們之間的耦合度,並且能讓你改變它們之間的互動獨立性。」

概念製作起來的話,就像下面FooColleagueBarColleauge引用FooMediator去做訊息的呼叫,而FooMediator本身也引用了IColleague讓訊息內容會因類別功能差異而有所變化。

IMediator.cs

namespace LinXuan.DesignPattern.Example.Mediator 
{ 
    public interface IMediator 
    { 
        public void SendMessage(IColleague colleague, string Message); 
    } 
}

IColleague.cs

namespace LinXuan.DesignPattern.Example.Mediator 
{ 
    public abstract class IColleague 
    { 
        protected IMediator m_Mediator = null; 
        public IColleague(IMediator mediator) 
        { 
            m_Mediator = mediator; 
        } 
        public abstract void Request(string Message); 
    } 
}

Colleagues.cs

using UnityEngine; 

namespace LinXuan.DesignPattern.Example.Mediator 
{ 
    public class FooColleague : IColleague 
    { 
        public FooColleague(IMediator mediator) : base(mediator) 
        { 
        } 
        public void SendMessage() 
        { 
            m_Mediator.SendMessage(this, "FooColleague send message."); 
        } 
        public override void Request(string message) 
        { 
            Debug.Log("FooColleague.Request " + message); 
        } 
    } 
    public class BarColleague : IColleague 
    { 
        public BarColleague(IMediator mediator) : base(mediator) 
        { 
        } 
        public void SendMessage() 
        { 
            m_Mediator.SendMessage(this, "BarColleague send message."); 
        } 
        public override void Request(string message) 
        { 
            Debug.Log("BarColleague.Request " + message); 
        } 
    } 
}

FooMediator.cs

namespace LinXuan.DesignPattern.Example.Mediator 
{ 
    public class FooMediator : IMediator 
    { 
        FooColleague m_FooColleague = null; 
        BarColleague m_BarColleague = null; 
        public void SetFooColleague(FooColleague fooColleague) 
        { 
            m_FooColleague = fooColleague; 
        } 
        public void SetBarColleague(BarColleague barColleague) 
        { 
            m_BarColleague = barColleague; 
        } 
        public void SendMessage(IColleague colleague, string message) 
        { 
            if (m_FooColleague == colleague) 
                m_FooColleague.Request(message); 
            if (m_BarColleague == colleague) 
                m_BarColleague.Request(message); 
        } 
    } 
}

MediatorTest.cs

using UnityEngine; 
namespace LinXuan.DesignPattern.Example.Mediator 
{ 
    public class MediatorTest : MonoBehaviour 
    { 
        private void Start() 
        { 
            FooMediator fooMediator = new FooMediator(); 
            FooColleague fooColleague = new FooColleague(fooMediator); 
            BarColleague barColleague = new BarColleague(fooMediator); 
            fooMediator.SetFooColleague(fooColleague); 
            fooMediator.SetBarColleague(barColleague); 
            fooColleague.SendMessage(); 
            barColleague.SendMessage(); 
        } 
    } 
}

輸出如下
https://ithelp.ithome.com.tw/upload/images/20220928/20151894uNaVaE3Mbq.png

實際案例

如果以CALGUIControllerFleeEvent來說,因為CALGUIController直接引用CellGrid這個主要控制遊戲系統的程式,而有個功能是要製作當角色逃跑時的一連串行動與UI呼叫的觸發,而此時CellGrid就負責了大部分相關功能的呼叫,並在SetFleeButtonEvent去設定StageTooltipGUI的Button引用此function。

CALGUIController.cs

private void Awake()
{
    ...
    SetFleeButtonEvent();
    ...
}

private void SetFleeButtonEvent()
{
    m_StageTooltipGUI.SetFleeButton(FleeEvent);
}

private void FleeEvent()
{
    CellGrid.CellGridState = new CALBlockInputCellGridState(CellGrid);
    UIInputObserver.FleeAction.Invoke();
    m_StageTooltipGUI.SetFleeTooltipText();
    m_StageTooltipGUI.SetFleeButtonIsActive(false);
    CellGrid.CheckGameFinished();
    m_IsUnitClicked = false;
    m_CurrentSelectUnit = default(Unit);
    SetPlayerInfoIsActive(default, false);
    if(!CellGrid.GameFinished)
        CellGrid.CellGridState = new CALWaitingForInputCellGridState(CellGrid);
}

參考資料

設計模式與遊戲開發的完美結合(暢銷回饋版)
Turn Based Strategy Framework
流離之歌


上一篇
Day 13:Facade模式
下一篇
Day 15:Factory模式(一)
系列文
如何在Unity裡寫出具有一定擴充性的遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言