Unity - 对PureMVC的理解和应用

#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<InputField>();
            input2 = root.Find("Input2").GetComponent<InputField>();
            result = root.Find("Result").GetComponentInChildren<Text>();
            calculateButton = root.Find("Calculate").GetComponent<Button>();
            calculateButton.onClick.AddListener(OnButtonClick);
        }
        // UI的点击事件
        private void OnButtonClick()
        {
            float f1, f2;

            if (!System.Single.TryParse(input1.text, out f1))
            {
                HandleSelfNotification(MyEvent.INPUTERROR);
                return;
            }
            if (!System.Single.TryParse(input2.text, out f2))
            {
                HandleSelfNotification(MyEvent.INPUTERROR);
                return;
            }
            MyProxy proxy = (MyProxy)Facade.RetrieveProxy(MyProxy.NAME);
            proxy.SetInput(f1, f2);
            SendNotification(MyEvent.CALCULATE);
        }
        // 感兴趣的Event
        public override IList<string> ListNotificationInterests()
        {
            IList<string> list = new List<string>();
            list.Add(MyEvent.RESULT);
            return list;
        }
        // 处理感兴趣的Event
        public override void HandleNotification(PureMVC.Interfaces.INotification notification)
        {
            switch (notification.Name)
            {
                case MyEvent.RESULT:
                    float ret = (float)notification.Body;
                    result.text = ret.ToString();
                    input1.text = string.Empty;
                    input2.text = string.Empty;
                    break;
                default:
                    break;
            }
        }

        public void HandleSelfNotification(string notificationName)
        {
            switch (notificationName)
            {
                case MyEvent.INPUTERROR:
                    result.text = "输入错误!";
                    input1.text = string.Empty;
                    input2.text = string.Empty;
                    break;
                default:
                    break;
            }
        }
    }
}
// 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

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值