PureMVC在Unity游戏开发中的应用

作为开发人员,我们都想写出优雅的代码,可又苦于自身能力不知该如何下手,而框架的作用正在与能够让你规范的去开发。

之前写Web的时候,总被要求采用MVC架构,的确非常好用,也从来没有质疑过这种架构的好与不好。直到做游戏开发后,发现MVC架构其实很难应对游戏软件的各种需求,诸如实时战斗等。MVC特别适用于UI部分的开发,所以pureMVC我们同样也主要用在UI方面,凡是与UI有一定交互的部分,我们都可以通过MVC进行架构。


PureMVC

PureMVC框架在Unity中的应用

官方中文文档

pureMVC源码链接 选择standard版本

传统MVC在使用上,View和Controller耦合度太高,很多逻辑代码既可以写在View层又可以写在Controller层,而pureMVC引入中介者模式+消息机制来进行解耦。pureMVC仍然由Model-Controller-View组成,并且通过Facade统一进行管理。

Model层,采用代理模式,由Proxy处理数据访问,增删改查均是通过Proxy来处理,当检测到数据改变后会发送消息Notification通知View和Controller
View层,采用中介者模式,由Mediator处理数据交互,通知Controller进行逻辑处理。
Controller层,采用命令模式Command拆分逻辑,便于复用。


简单示例

以点击Button改变Text为例讲解pureMVC
PureMVC在Unity游戏开发中的应用_第1张图片
GameManager.cs

// 任意文件
using UnityEngine;
// 继承mon
public class GameManager : MonoBehaviour
{
    void Start()
    {
    	// 实例化Facade
        MyFacade myFacade = new MyFacade(gameObject);
    }
}

MyFacede.cs

// pureMVC入口文件
using UnityEngine;
using PureMVC.Patterns.Facade;
// 继承Facede
public class MyFacade : Facade
{
    public MyFacade(GameObject root)
    {
		// 注册Controller Command
        RegisterCommand("REG_ADD", () =>
        {
            return new MyDataCommandAdd();
        });
        // 注册View Mediator
        RegisterMediator(new MyDataMediator(root));
        // 注册Model Proxy
        RegisterProxy(new MyDataProxy());
    }
}

Model层

// MyData.cs 数据文件
public class MyData
{
    public int value;
}
// MyDataProxy.cs 代理文件
using PureMVC.Patterns.Proxy;
// 继承Proxy
public class MyDataProxy : Proxy
{
	// name 必须
    public const string proxyName = "MYDATAPROXY";
    public MyData mydata = null;
    // 构造 实例化数据
    public MyDataProxy() : base(proxyName)
    {
        mydata = new MyData();
    }
    // add方法,发送"MSG_ADD"消息
    public void AddValue()
    {
        mydata.value++;
        SendNotification("MSG_ADD", mydata);
    }
    public override void SendNotification(string notificationName, object body = null, string type = null)
    {
        base.SendNotification(notificationName, body, type);
    }
}

View层

// MyDataMediator.cs 中介者文件
using UnityEngine;
using PureMVC.Patterns.Mediator;
using UnityEngine.UI;
using PureMVC.Interfaces;
// 继承Mediator
public class MyDataMediator : Mediator
{
	// name 必须
    public const string mediatorName = "Mediator";
    public Text textNum;
    public Button add;
    public Button sub;
    public MyDataMediator(GameObject root) : base (mediatorName)
    {
    	// 通过Find获取视图引用
        textNum = root.transform.Find("Text").GetComponent<Text>();
        add = root.transform.Find("Add").GetComponent<Button>();
        sub = root.transform.Find("Sub").GetComponent<Button>();
		// 添加事件
        add.onClick.AddListener(AddBtnClick);
        sub.onClick.AddListener(SubBtnClick);
    }
    // 接收消息列表 必须
    public override string[] ListNotificationInterests()
    {
        string[] list = new string[] { "MSG_ADD" };
        return list;
    }
    /// 消息处理 必须
    public override void HandleNotification(INotification notification)
    {
        switch(notification.Name)
        {
            case "MSG_ADD":
                Display(notification.Body as MyData);
                break;
            default:
                break;
        }
    }
    public void Display(MyData myData)
    {
        textNum.text = myData.value.ToString();
    }
    public void AddBtnClick()
    {
        SendNotification("REG_ADD");
    }
    public override void SendNotification(string notificationName, object body = null, string type = null)
    {
        base.SendNotification(notificationName, body, type);
    }
}

Controller层

// MyDataCommandAdd.cs 命令文件
using PureMVC.Patterns.Command;
using PureMVC.Interfaces;
// 继承SimpleCommand
public class MyDataCommandAdd : SimpleCommand
{
	// 重写 Execute
    public override void Execute(INotification notification)
    {
    	// RetrieveProxy 调用add方法
        MyDataProxy myDataProxy = Facade.RetrieveProxy("MYDATAPROXY") as MyDataProxy;
        myDataProxy.AddValue();
    }
}

流程理解

  1. 当点击View界面的Button后,由Mediator开始处理,通过pureMVC提供的SendNotification方法通知Controller
  2. Controller接收到消息后,由相应的"REG_ADD"命令(Command)进行处理,调用Facade的RetrieveProxy方法访问数据
  3. Model数据由Proxy代为管理,当数据发生变化后由Proxy通过SendNotification通知View改变视图。
    PureMVC在Unity游戏开发中的应用_第2张图片

个人理解

pureMVC突出一个"中介"的思想,通过设计模式对MVC框架进行了解耦,Facade 外观模式、Proxy 代理模式、Mediator 中介者模式、Command 命令模式,pureMVC的消息机制通过观察者模式实现。基于这些设计,以此凸显pure的概念。

你可能感兴趣的:(unity)