仲介者模式(Mediator)在GoF中的說明是:
「定義一個介面用來包裝一群物件的互動行為。仲介者藉由移除物件間的引用,來減少它們之間的耦合度,並且能讓你改變它們之間的互動獨立性。」
概念製作起來的話,就像下面FooColleague
跟BarColleauge
引用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();
}
}
}
輸出如下
如果以CALGUIController
的FleeEvent
來說,因為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
流離之歌