外觀模式(Facade)在GoF 的解釋是:
「替子系統定義一組統一的介面,這個高階的介面會讓子系統更容易被使用。」
使用Facade的最大優點,就是將系統內部的互動細節隱藏起來,並提供一個方式給予其他人使用。
以一個蠻常見的設計例子來說,我們會希望有一個介面可以讓我們擁有獲取三種圖形的畫法、而不是去一個個重新創造跟呼叫,在此例子中這個介面就是ShapeMaker
。
IShape.cs
namespace LinXuan.DesignPattern.Example.Facade
{
public interface IShape
{
public void Draw();
}
}
Shapes.cs
using UnityEngine;
namespace LinXuan.DesignPattern.Example.Facade
{
public class Rectangle : IShape
{
public void Draw()
{
Debug.Log("Rectangle draw.");
}
}
public class Square : IShape
{
public void Draw()
{
Debug.Log("Square draw.");
}
}
public class Circle : IShape
{
public void Draw()
{
Debug.Log("Circle draw.");
}
}
}
ShapeMaker.cs
namespace LinXuan.DesignPattern.Example.Facade
{
class ShapeMaker
{
private IShape m_Circle;
private IShape m_Rectangle;
private IShape m_Square;
public ShapeMaker()
{
m_Circle = new Circle();
m_Rectangle = new Rectangle();
m_Square = new Square();
}
public void DrawCircle()
{
m_Circle.Draw();
}
public void DrawRectangle()
{
m_Rectangle.Draw();
}
public void DrawSquare()
{
m_Square.Draw();
}
}
}
FacadeTest.cs
using UnityEngine;
namespace LinXuan.DesignPattern.Example.Facade
{
public class FacadeTest : MonoBehaviour
{
private void Start()
{
ShapeMaker shapeMaker = new ShapeMaker();
shapeMaker.DrawCircle();
shapeMaker.DrawRectangle();
shapeMaker.DrawSquare();
}
}
}
CALGUIController.cs
public class CALGUIController : MonoBehaviour
{
public CellGrid CellGrid;
[SerializeField] private Button m_EndTurnButton;
[SerializeField] private Button m_SettingButton;
[SerializeField] private CALFightGUI m_FightGUI;
[SerializeField] private OptionsGUI m_OptionsGUI;
[SerializeField] private StageTooltipGUI m_StageTooltipGUI;
[SerializeField] private CharacterInformationGUI m_CharacterInfomationGUI;
private void Awake()
{
...
m_OptionsGUI.SetSettingButton(CALActionHandler.OpenSettingGUI);
m_OptionsGUI.SetSaveAndLeaveButton();
m_OptionsGUI.SetReturnMenuButton();
m_StageTooltipGUI.SetFleeTooltipText();
...
}
...
private void FoodCollectedUpdate(object sender, FoodCountEventArgs e)
{
m_StageTooltipGUI.SetFoodCount(e.FoodCollectedCount, e.FoodOfNeedCount);
}
}
如果以CALGUIController
來說,我就是會在這邊去宣告相關GUI的初始化,而也有FoodCollectedUpdate
來對外更新StageTooltipGUI裡的資料。
不過這樣做要注意一個點,當Facade類別過大時,要將功能相近的子系統再整合,或利用其他設計模式重構,這個部分可以參考之後會說到的Observer模式。
設計模式與遊戲開發的完美結合(暢銷回饋版)
Turn Based Strategy Framework
流離之歌