作为开发人员,我们都想写出优雅的代码,可又苦于自身能力不知该如何下手,而框架的作用正在与能够让你规范的去开发。
之前写Web的时候,总被要求采用MVC架构,的确非常好用,也从来没有质疑过这种架构的好与不好。直到做游戏开发后,发现MVC架构其实很难应对游戏软件的各种需求,诸如实时战斗等。MVC特别适用于UI部分的开发,所以pureMVC我们同样也主要用在UI方面,凡是与UI有一定交互的部分,我们都可以通过MVC进行架构。
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
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();
}
}
pureMVC突出一个"中介"的思想,通过设计模式对MVC框架进行了解耦,Facade 外观模式、Proxy 代理模式、Mediator 中介者模式、Command 命令模式,pureMVC的消息机制通过观察者模式实现。基于这些设计,以此凸显pure的概念。