PureMVC顾名思义,比MVC更纯净的MVC架构,相比与MVC它耦合性更低、代码重用性更高,当然缺点也比较明显:事件的传递都要经过拆箱装箱、事件的执行都需要用反射性能不高、代码冗余。但不失为新手学习的好框架,也可以直接放到项目中应用。
##PureMVC核心
对应设计模式的外观模式:http://www.runoob.com/design-pattern/facade-pattern.html。 它是PureMVC的外部入口,用于初始化Model、View、Controller,可以操作任何的Proxy、Mediator、Command。
对应设计模式的代理模式:http://www.runoob.com/design-pattern/proxy-pattern.html。 Proxy接受Command、Mediator的通知,对数据(图中的Data Objects)进行处理,并把结果保存到数据中。
对应设计模式的中介者模式:http://www.runoob.com/design-pattern/mediator-pattern.html。 对UI的操作由Mediator来管理,包括添加事件监听,发送或接受Notification,改变UI状态等。图中的View Components在Unity中对应的就是封装好的UI.Image、UI.Text等组件。Mediator可以直接对Proxy进行操作,并接受Command的通知。
对应设计模式的命令模式:http://www.runoob.com/design-pattern/command-pattern.html。 Controller已经在Facade中被隐式创建好,因此只需要创建对应的Command并用Facade注册即可。Command控制Proxy中的数据该如何处理,将结果通知Proxy进行存储,命令完成后通知Mediator显示结果。
各个模块的消息传递都是用观察者模式: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