1. 程式人生 > >Unity 基於 Facade 外觀模式 進行開發..

Unity 基於 Facade 外觀模式 進行開發..

enume new 打印 接口 success 自定義 not temp param

Facade模式的開發利弊我這裏就不一一指出了,已經有很多大神都做了詳細的講解..

我這裏只是模擬一下,通過 服務端下發消息 也就是 消息層 並將消息做一些處理 分發到 數據層 再通過一系列解析 分發到UI層..

Unity 新建 如下文件夾:

技術分享圖片

Interface 中新建三個 接口,名稱自定義,

我這裏是 : 技術分享圖片

IDataProxy:

/***
 *
 *   Title: 接口代理處理
 *
 *   Description: 所有Module繼承,用來添加,接收消息處理
 *
 *   Author:
 *
 *   Date: 2019.3.26
 *
 *   Modify: 
 * 
 
*/ using System; public interface IDataProxy { /// <summary> /// 添加消息 /// </summary> /// <param name="dataType">消息類型</param> /// <param name="data">消息</param> void OnAddData (int dataType, object data); /// <summary> /// 初始化 /// </summary>
void OnInit (); /// <summary> /// 清除數據 /// </summary> void OnDestroy (); }

IUIMediator:

/*********************************************
 *
 *   Title: UI傳遞層
 *
 *   Description: 通過MsgHandle服務器消息傳遞,下發給UI層
 *
 *   Author: 自律
 *
 *   Date: 2019.3.26
 *
 *   Modify: 
 * 
 ********************************************
*/ using System; public interface IUIMediator { /// <summary> /// 接收到數據消息 /// </summary> /// <param name="nType">N type.</param> /// <param name="nData">N data.</param> void OnRecvData (int uiType, object nData); /// <summary> /// 初始化 /// </summary> void OnInit (); /// <summary> /// 釋放數據 /// </summary> void OnRelease (); }

IMsgHandle:

/*********************************************
 *
 *   Title: 消息處理接口
 *
 *   Description: 初始化消息,和清空消息
 *
 *   Author: 自律
 *
 *   Date: 2019.3.26
 *
 *   Modify: 
 * 
 *********************************************/
using System;

public interface IMsgHandle
{
    void OnInit ();

    void OnDestroy ();
}

Config文件夾下創建FacadeConfig.cs:

/*********************************************
 *
 *   Title: Facade配置表單
 *
 *   Description: 添加Type類型
 *
 *   Author: 自律
 *
 *   Date: 2019.3.26
 *
 *   Modify: 
 * 
 *********************************************/
using System;

/// <summary>
/// Facade配置表單,添加Type類型
/// </summary>
public class FacadeConfig
{
    /// <summary>
    /// 測試 DATA 數據1
    /// </summary>
    public const int MYTEST_MUDULE_DATA_1 = 1;
    /// <summary>
    /// 測試 DATA 數據2
    /// </summary>
    public const int MYTEST_MUDULE_DATA_2 = 2;

    /// <summary>
    /// 測試 MsgHandle 數據 1
    /// </summary>
    public const int MYTEST_MUDULE_MSG_1 = 3;
    /// <summary>
    /// 測試 MsgHandle 數據 12
    /// </summary>
    public const int MYTEST_MUDULE_MSG_2 = 4;
    /// <summary>
    /// 測試 UIView 數據 12
    /// </summary>
    public const int MYTEST_MUDULE_UI_1 = 5;

    public  FacadeConfig ()
    {
        
    }
}

Module目錄下創建:DataModule,Facade,MessageModul,UIViewModule 四個腳本:

DataModule:

/*********************************************
 *
 *   Title: 
 *
 *   Description: 
 *
 *   Author: 自律
 *
 *   Date: 
 *
 *   Modify: 
 * 
 *********************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DataModule
{
    /// <summary>
    /// 數據字典
    /// </summary>
    private Dictionary<int,IDataProxy> dataDictionary = new Dictionary<int, IDataProxy> ();
    const string TAG = "[ DataModule ]";

    /// <summary>
    /// 構造函數
    /// </summary>
    public DataModule ()
    {
        
    }

    /// <summary>
    /// 初始化消息
    /// </summary>
    public void InitModule ()
    {
        //這裏去添加事件  測試Test1
        TestInfoFirst mTest1 = new TestInfoFirst ();
        Add (FacadeConfig.MYTEST_MUDULE_DATA_1, mTest1);

        TestInfoSecond mTest2 = new TestInfoSecond ();
        Add (FacadeConfig.MYTEST_MUDULE_DATA_2, mTest2);

        Debug.Log (TAG + " init success !!! ");
    }

    /// <summary>
    /// 清空Data層Module
    /// </summary>
    public void DestroyModule ()
    {
        foreach (KeyValuePair<int,IDataProxy> data in dataDictionary) {
            //這裏去清除所有的消失事件
            data.Value.OnDestroy ();
        }
        //Clear字典裏存儲的數據
        dataDictionary.Clear ();
        Debug.Log (TAG + "dataDictionary.Count : " + dataDictionary.Count);
    }

    /// <summary>
    /// 添加數據模塊的分數據
    /// </summary>
    /// <param name="dataType">Data type.</param>
    /// <param name="dataProxy">Data proxy.</param>
    public void Add (int dataType, IDataProxy dataProxy)
    {
        //如果字典中沒有該key值,就添加,預防重復添加數據
        if (!dataDictionary.ContainsKey (dataType)) {
            dataDictionary.Add (dataType, dataProxy);
        }
    }

    /// <summary>
    /// 獲取Data模塊的分數據
    /// </summary>
    /// <returns>The data.</returns>
    /// <param name="dataType">Data type.</param>
    public IDataProxy GetData (int dataType)
    {
        if (dataDictionary.ContainsKey (dataType)) {
            return dataDictionary [dataType];
        }
        Debug.Log (TAG + "GetData = null!!! please check!");
        return null;
    }

    /// <summary>
    /// 移除分數據
    /// </summary>
    /// <param name="dataType">Data type.</param>
    public void Remove (int dataType)
    {
        if (dataDictionary.ContainsKey (dataType)) {
            dataDictionary.Remove (dataType);
        }
    }
}

MessageModul:

/***
 *
 *   Title: 
 *
 *   Description: 
 *
 *   Author: 自律
 *
 *   Date: 
 *
 *   Modify: 
 * 
 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MessageModule
{
    /// <summary>
    /// 消息處理字典
    /// </summary>
    private Dictionary<int,IMsgHandle> msgHandleDic = new Dictionary<int, IMsgHandle> ();
    const string TAG = "[ MessageModule ]";

    public MessageModule ()
    {
        
    }

    /// <summary>
    /// 獲取消息事件
    /// </summary>
    /// <returns>The message.</returns>
    /// <param name="msgType">Message type.</param>
    private IMsgHandle GetMsg (int msgType)
    {
        if (!msgHandleDic.ContainsKey (msgType)) {
            Debug.Log (TAG + "GetMsg failed! msgHandleDic does not contains this Key, please check!");
            return null;
        }
        return msgHandleDic [msgType];
    }

    /// <summary>
    /// 測試1數據
    /// </summary>
    /// <value>The test1.</value>
    public TestMsgHandle1 test1 {
        get {
            return (TestMsgHandle1)GetMsg (FacadeConfig.MYTEST_MUDULE_MSG_1);
        }
    }

    /// <summary>
    /// 測試2數據
    /// </summary>
    /// <value>The test2.</value>
    public TestMsgHandle2 test2 {
        get {
            return (TestMsgHandle2)GetMsg (FacadeConfig.MYTEST_MUDULE_MSG_2);
        }
    }

    /// <summary>
    /// 初始化Message Module
    /// </summary>
    public void  InitModule ()
    {
        //這裏添加註冊事件
        TestMsgHandle1 testMsg1 = new TestMsgHandle1 ();
        AddMsgEvent (FacadeConfig.MYTEST_MUDULE_MSG_1, testMsg1);

        TestMsgHandle2 testMsg2 = new TestMsgHandle2 ();
        AddMsgEvent (FacadeConfig.MYTEST_MUDULE_MSG_2, testMsg2);
    }

    /// <summary>
    /// 清空字典移除消息
    /// </summary>
    public void DestroyModule ()
    {
        //var eumDic = msgHandleDic.GetEnumerator ();  這種方式也可以,網絡上測試說 var 的效率更快
        Dictionary<int,IMsgHandle>.Enumerator eumDic = msgHandleDic.GetEnumerator ();
        while (eumDic.MoveNext ()) {
            //將msg的事件清除
            eumDic.Current.Value.OnDestroy ();
        }
        msgHandleDic.Clear ();
    }

    /// <summary>
    /// 添加消息事件
    /// </summary>
    /// <param name="msgType">Message type.</param>
    /// <param name="msgHandle">Message handle.</param>
    public void AddMsgEvent (int msgType, IMsgHandle msgHandle)
    {
        //如果消息字典沒有該鍵值,就添加事件
        if (!msgHandleDic.ContainsKey (msgType)) {
            //添加消息 
            msgHandleDic.Add (msgType, msgHandle);
            //初始化
            msgHandle.OnInit ();
        }
    }

    /// <summary>
    /// 移除消息事件
    /// </summary>
    /// <param name="msgType">Message type.</param>
    /// <param name="msgHandle">Message handle.</param>
    public void RemoveEvent (int msgType)
    {
        //如果字典有該鍵值,就給他移除,並執行 MsgHandle 的 OnDestroy
        if (msgHandleDic.ContainsKey (msgType)) {
            msgHandleDic [msgType].OnDestroy ();
            msgHandleDic.Remove (msgType);
        }
    }
}

UIViewModule:

/***
 *
 *   Title: 
 *
 *   Description: 
 *
 *   Author: 自律
 *
 *   Date: 
 *
 *   Modify: 
 * 
 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIViewModule
{
    /// <summary>
    /// UI傳輸層字典
    /// </summary>
    private Dictionary<int,IUIMediator> uiMediatorDic = new Dictionary<int, IUIMediator> ();
    const string TAG = "[ UIViewModule ]";

    /// <summary>
    /// 構造函數
    /// </summary>
    public UIViewModule ()
    {
        
    }

    /// <summary>
    /// 初始化UI模塊
    /// </summary>
    public void InitModule ()
    {

    }

    /// <summary>
    /// 清空UI模塊
    /// </summary>
    public void DestroyModule ()
    {
        Dictionary <int,IUIMediator>.Enumerator eumMediator = uiMediatorDic.GetEnumerator ();
        while (eumMediator.MoveNext ()) {
            eumMediator.Current.Value.OnRelease ();
        }
        uiMediatorDic.Clear ();
    }

    /// <summary>
    /// 添加UI事件
    /// </summary>
    /// <param name="uiType">User interface type.</param>
    /// <param name="uiMediator">User interface mediator.</param>
    public void AddUIEvent (int uiType, IUIMediator uiMediator)
    {
        //這裏是因為 可以添加重復的UI事件,如果添加非空判斷,會導致新事件進不來
        if (uiMediatorDic.ContainsKey (uiType)) {
            uiMediatorDic.Remove (uiType);
        }
        uiMediatorDic.Add (uiType, uiMediator);
        //初始接口裏的所有事件
        uiMediator.OnInit ();
    }

    /// <summary>
    /// 獲取UI消息
    /// </summary>
    /// <returns>The user interface mediator.</returns>
    /// <param name="uiType">User interface type.</param>
    public IUIMediator GetUIMediator (int uiType)
    {
        if (uiMediatorDic.ContainsKey (uiType)) {
            return uiMediatorDic [uiType];
        } else {
            Debug.Log (TAG + "GetUIMediator failed! please check!");
            return null;
        }
    }

    /// <summary>
    /// 移除UI事件
    /// </summary>
    /// <param name="nType">N type.</param>
    public void Remove (int uiType)
    {
        if (uiMediatorDic.ContainsKey (uiType)) {
            uiMediatorDic [uiType].OnRelease ();
            uiMediatorDic.Remove (uiType);
        }
    }
}

Facade:

/***
 *
 *   Title: Facade總類
 *
 *   Description: 所有類的入口
 *
 *   Author: 自律
 *
 *   Date: 2019.3.26
 *
 *   Modify: 
 * 
 */
using System.Collections;
using System;

public class Facade
{
    private static Facade Instance = new Facade ();
    /// <summary>
    /// 數據模塊
    /// </summary>
    private DataModule dataModule;
    /// <summary>
    /// UI視圖模塊
    /// </summary>
    private UIViewModule uiViewModule;
    /// <summary>
    /// 消息處理模塊
    /// </summary>
    private MessageModule messageModule;

    /// <summary>
    /// 構造函數
    /// </summary>
    private Facade ()
    {
        
    }

    /// <summary>
    /// 單例
    /// </summary>
    /// <returns>The facade.</returns>
    public static Facade GetFacade ()
    {
        return Instance;
    }

    /// <summary>
    /// 獲取數據模塊
    /// </summary>
    /// <value>The data.</value>
    public DataModule Data {
        get {
            return dataModule;
        }
    }

    /// <summary>
    /// 獲取UI模塊
    /// </summary>
    /// <value>The user interface.</value>
    public UIViewModule UIView {
        get {
            return uiViewModule;
        }
    }

    /// <summary>
    /// 獲取消息模塊
    /// </summary>
    /// <value>The message.</value>
    public MessageModule Message {
        get {
            return messageModule;
        }
    }

    /// <summary>
    /// 初始化所有模型
    /// </summary>
    public void InitAllModule ()
    {
        dataModule = new DataModule ();
        messageModule = new MessageModule ();
        uiViewModule = new UIViewModule ();
        //所有消息都進行初始化inits
        dataModule.InitModule ();
        messageModule.InitModule ();
        uiViewModule.InitModule ();
    }

    public void DestroyAllModule ()
    {
        if (dataModule != null) {
            //dataModule.de ();
        }
        if (uiViewModule != null) {
            //uiViewModule.de ();
        }
        if (messageModule != null) {
            //messageModule.de ();
        }
        dataModule = null;
        uiViewModule = null;
        messageModule = null;
    }
}

接下來開始書寫測試內容:

Message 文件下 創建 : TestMsgHandle1 , TestMsgHandle2 兩個腳本

TestMsgHandle1:

/*********************************************
 *
 *   Title: 
 *
 *   Description: 
 *
 *   Author: 自律
 *
 *   Date: 
 *
 *   Modify: 
 * 
 *********************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestMsgHandle1 : IMsgHandle
{
    public void OnInit ()
    {
        
    }

    public void OnDestroy ()
    {
        
    }

    public void SendTest1Msg ()
    {
        Debug.Log ("TestMsgHandle1 SendTest1Msg = 1");
        //模擬服務器數據,當消息發出時候,會得到相應的回復
        RcvTest1Msg (0);
    }

    public void RcvTest1Msg (int result)
    {
        if (result == 0) {
            Debug.Log ("TestMsgHandle1 RcvTest1Msg = 1");
            Facade.GetFacade ().UIView.GetUIMediator (FacadeConfig.MYTEST_MUDULE_UI_1).OnRecvData (result, "Test");
        }
    }
}

TestMsgHandle2:

/*********************************************
 *
 *   Title: 
 *
 *   Description: 
 *
 *   Author: 自律
 *
 *   Date: 
 *
 *   Modify: 
 * 
 *********************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestMsgHandle2 : IMsgHandle
{

    public void OnInit ()
    {

    }

    public void OnDestroy ()
    {

    }

    public void SendTest2Msg ()
    {
        Debug.Log ("TestMsgHandle2 SendTest2Msg = 1");
        //模擬服務器數據,當消息發出時候,會得到相應的回復
        RcvTest2Msg (1);
    }

    public void RcvTest2Msg (int result)
    {
        if (result == 1) {
            Debug.Log ("TestMsgHandle2 RcvTest2Msg = 1,--" + result);
            IUIMediator uiMediator = Facade.GetFacade ().UIView.GetUIMediator (FacadeConfig.MYTEST_MUDULE_UI_1);
            if (uiMediator != null) {
                uiMediator.OnRecvData (2, false);
            }
        }
    }
}

Data 文件夾下創建 : TestInfoFirst,TestInfoSecond兩個腳本

TestInfoFirst:

/*********************************************
 *
 *   Title: 測試數據1
 *
 *   Description: 
 *
 *   Author: 自律
 *
 *   Date: 
 *
 *   Modify: 
 * 
 *********************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestInfoFirst:IDataProxy
{

    List<int> intTest = new List<int> ();

    /// <summary>
    /// 構造函數
    /// </summary>
    public TestInfoFirst ()
    {
        
    }

    /// <summary>
    /// 析構函數
    /// </summary>
    ~TestInfoFirst ()
    {
        
    }

    public    void OnAddData (int dataType, object data)
    {
        
    }

    public    void OnInit ()
    {
        Debug.Log ("TestInfoFirst OnInit intTest Count = " + intTest.Count);
    }

    public    void OnDestroy ()
    {
        intTest.Clear ();
    }

    public void TestDebug ()
    {
        for (int i = 0; i < 5; i++) {
            if (intTest.Contains (i)) {
                return;
            } else {
                intTest.Add (i);
            }
        }
        Debug.Log ("TestInfoFirst TestDebug intTest Count = " + intTest.Count);
    }
}

TestInfoSecond:

/*********************************************
 *
 *   Title: 
 *
 *   Description: 
 *
 *   Author: 自律
 *
 *   Date: 
 *
 *   Modify: 
 * 
 *********************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestInfoSecond : IDataProxy
{

    /// <summary>
    /// 構造函數
    /// </summary>
    public TestInfoSecond ()
    {

    }

    /// <summary>
    /// 析構函數
    /// </summary>
    ~TestInfoSecond ()
    {

    }

    public    void OnAddData (int dataType, object data)
    {

    }

    public    void OnInit ()
    {

    }

    public    void OnDestroy ()
    {

    }

    public void TestDebug ()
    {
        Debug.Log ("TestInfoSecond Debug 測試2");
    }
}

UI文件夾中生成 UITest腳本

UITest:

/*********************************************
 *
 *   Title: 
 *
 *   Description: 
 *
 *   Author: 自律
 *
 *   Date: 
 *
 *   Modify: 
 * 
 *********************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UITest : MonoBehaviour,IUIMediator
{

    public Image imgae;
    public Text text;
    private Facade facadeTemp = null;

    void Awake ()
    {
        facadeTemp = Facade.GetFacade ();
        //先清空所有數據,在進行初始化
        facadeTemp.DestroyAllModule ();
        facadeTemp.InitAllModule ();
        Facade.GetFacade ().UIView.AddUIEvent (FacadeConfig.MYTEST_MUDULE_UI_1, this);
    }

    void Update ()
    {
        //測試1的打印消息
        if (Input.GetKeyDown (KeyCode.A)) {
            TestInfoFirst first = (TestInfoFirst)Facade.GetFacade ().Data.GetData (FacadeConfig.MYTEST_MUDULE_DATA_1);
            first.TestDebug ();
        }
        //測試2的打印消息
        if (Input.GetKeyDown (KeyCode.S)) {
            TestInfoSecond second =    (TestInfoSecond)Facade.GetFacade ().Data.GetData (FacadeConfig.MYTEST_MUDULE_DATA_2);
            second.TestDebug ();
        }
        if (Input.GetKeyDown (KeyCode.D)) {
            Facade.GetFacade ().Message.test1.SendTest1Msg ();
        }
        if (Input.GetKeyDown (KeyCode.W)) {
            Facade.GetFacade ().Message.test2.SendTest2Msg ();
        }
    }

    /// <summary>
    /// 有兩種調用方式
    /// 第一種: Facade.GetFacade ().UIView.GetUIMediator (Your Type).OnRecvData (type,data);
    /// 第二張:IUIMediator uiMediator = Facade.GetFacade ().UIView.GetUIMediator (Your Type);
    /// if (uiMediator != null) {
    ///     uiMediator.OnRecvData (type,data);
    ///    }
    /// 
    /// </summary>
    /// <param name="nType">N type.</param>
    /// <param name="nData">N data.</param>
    /// <param name="uiType">User interface type.</param>
    public void OnRecvData (int uiType, object nData)
    {
        switch (uiType) {
        case 0:
            text.text = (string)nData;
            break;
        case 2:
            imgae.gameObject.SetActive ((bool)nData);
            break;
        default:
            break;
        }
    }

    public void OnInit ()
    {
        
    }

    public void OnRelease ()
    {
        
    }

    void OnDestory ()
    {
        Facade.GetFacade ().UIView.Remove (FacadeConfig.MYTEST_MUDULE_UI_1);
    }
}

新建場景新建一個Canvas,生成一個 Image 和 Text,進行拖拽,運行即可...

上述代碼都有註釋..這個只是自己寫的,可能會有bug存在,自己也只是寫個心得...所以請大家多多指點小菜鳥..

Unity 基於 Facade 外觀模式 進行開發..