iT邦幫忙

2022 iThome 鐵人賽

DAY 13
1

外觀模式(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
流離之歌


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

尚未有邦友留言

立即登入留言