Unity - 对PureMVC的理解和应用

PureMVC顾名思义,比MVC更纯净的MVC架构,相比与MVC它耦合性更低、代码重用性更高,当然缺点也比较明显:事件的传递都要经过拆箱装箱、事件的执行都需要用反射性能不高、代码冗余。但不失为新手学习的好框架,也可以直接放到项目中应用。
##PureMVC核心
这里写图片描述

Facade

对应设计模式的外观模式:http://www.runoob.com/design-pattern/facade-pattern.html。 它是PureMVC的外部入口,用于初始化Model、View、Controller,可以操作任何的Proxy、Mediator、Command。

Model与Proxy

对应设计模式的代理模式:http://www.runoob.com/design-pattern/proxy-pattern.html。 Proxy接受Command、Mediator的通知,对数据(图中的Data Objects)进行处理,并把结果保存到数据中。

View与Mediator

对应设计模式的中介者模式:http://www.runoob.com/design-pattern/mediator-pattern.html。 对UI的操作由Mediator来管理,包括添加事件监听,发送或接受Notification,改变UI状态等。图中的View Components在Unity中对应的就是封装好的UI.Image、UI.Text等组件。Mediator可以直接对Proxy进行操作,并接受Command的通知。

Contoller与Command

对应设计模式的命令模式:http://www.runoob.com/design-pattern/command-pattern.html。 Controller已经在Facade中被隐式创建好,因此只需要创建对应的Command并用Facade注册即可。Command控制Proxy中的数据该如何处理,将结果通知Proxy进行存储,命令完成后通知Mediator显示结果。

Notifier与Observer

各个模块的消息传递都是用观察者模式:http://www.runoob.com/design-pattern/observer-pattern.html 。Proxy、Mediator、Command都是Notifier,他们都会发消息,对这些消息感兴趣的都是Observer,比如Command会观察View的按钮、View观察Command的计算结果,初始时它们都会new一个Observer把函数名等保存到View中,执行时通过反射执行函数。

简单应用

一个简单的相加计算。
这里写图片描述

//MyEvent.cs所有事件
namespace PureMVCTest
{
    public class MyEvent
    {
        // 计算事件
        public const string CALCULATE = "Calculate";
        // 输入错误事件
        public const string INPUTERROR = "InputError";
        // 结果事件
        public const string RESULT = "Result";
    }
}
// MyProxy.cs
using PureMVC.Patterns;

namespace PureMVCTest
{
// Model数据结构
public struct Data
{
public float input1;
public float input2;
public float result;
}
// Model的代理
public class MyProxy : Proxy
{
public new const string NAME = “MyProxy”;
// 数据
protected Data m_Data;
public float input1 { get { return m_Data.input1; } }
public float input2 { get { return m_Data.input2; } }
public MyProxy() : base(NAME)
{

    }
    // 对Model数据的操作
    public void SetInput(float input1, float input2)
    {
        m_Data.input1 = input1;
        m_Data.input2 = input2;
    }
    public void SetResult(float result)
    {
        m_Data.result = result;
    }
}

}

// MyMediator.cs
using PureMVC.Patterns;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace PureMVCTest
{
    public class MyMediator : Mediator
    {
        public new const string NAME = "MyMediator";
        private InputField input1;
        private InputField input2;
        private Text result;
        private Button calculateButton;
        public MyMediator(Transform root)
        {
            input1 = root.Find("Input1").GetComponent();
            input2 = root.Find("Input2").GetComponent();
            result = root.Find("Result").GetComponentInChildren();
            calculateButton = root.Find("Calculate").GetComponent
// MyCommand.cs
using PureMVC.Interfaces;
using PureMVC.Patterns;

namespace PureMVCTest
{
    public class AddCommand : Notifier, ICommand
    {
        // 执行命令
        public void Execute(INotification notification)
        {
            MyProxy proxy = (MyProxy)Facade.RetrieveProxy(MyProxy.NAME);
            float result = proxy.input1 + proxy.input2;
            proxy.SetResult(result);
            SendNotification(MyEvent.RESULT, result);
        }
    }
}
// MyTest.cs挂载到Canvas上
using UnityEngine;

namespace PureMVCTest
{
    public class MyTest : MonoBehaviour
    {
        // 整个PureMVC的起点
        void Start()
        {
            PureMVC.Interfaces.IFacade facade = PureMVC.Patterns.Facade.Instance;
            // 初始化所有的Proxy、Mediator、Command
            facade.RegisterProxy(new MyProxy());
            facade.RegisterMediator(new MyMediator(transform));
            facade.RegisterCommand(MyEvent.CALCULATE, typeof(AddCommand));
        }
    }
}

执行顺序

UI OnButtonCilck事件 -> Mediator直接操作Proxy储存输入 -> Mediator发消息给Command -> Command执行命令,在Proxy中保存结果,并将结果发消息给Mediator -> Mediator接受消息改变显示

链接

PureMVC官网:http://puremvc.org/
PureMVC Github:https://github.com/PureMVC
参考文章:https://www.jianshu.com/p/47deaced9eb3

你可能感兴趣的:(项目架构)