整合PureMVC

PureMVC 概述

  1. PureMVC 是什么?
    PureMVC 是一个定位于设计高性能 RIA 客户端的基于模式的框架。目前已经被移植到多种语言(AS2、AS3、C#、ColdFusion、Haxe、JavaScript、Java、Objective C、PHP、Python、Ruby)和平台,包括服务器端环境。
  2. PureMVC 原理图示
  3. PureMVC 的两个版本
    PureMVC 分为标准(Standard)和多核(MultiCore)两个版本。后者目的在于进行模块化编程。[PureMVC – Multicore vs Standard / Singlecore]介绍了两个版本的本质区别。
  4. PureMVC 教程
    PureMVC Framework Goals and Benefits
    PureMVC Framework Overview with UML
    PureMVC Implementation Idioms and Best Practices
    PureMVC Implementation Idioms and Best Practices 简体中文(感谢张泽远和 Tamt 的翻译工作)

开始整合

  1. 注意事项:
    以下内容基于“Flex4系列教程之九”中最后形成的 sampleApp 项目。
  2. 准备所需组件
    下载 PureMVC(AS3) 多核版,将解压后的 PureMVC_AS3_MultiCore_1_0_5.swc 拷贝到 flex_libs 文件夹。
  3. 在 flex_src 下创建以下文件夹
    employees
    employees/controller     :放置 Command 类
    employees/model          :放置 Proxy 类
    employees/view           :放置 Mediator
    employees/view/components:放置视图文件(即 mxml 文件)
  4. 在继续之前,还是回顾一下 PureMVC 的原理吧
    记住一点:PureMVC 的通信并不采用 Flash 的 EventDispatcher/Event,而是使用观察者模式以一种松耦合的方式来实现的。

    所以要显示存储在数据库中的职员信息需经过以下过程:
    • View Component 触发一个 Event;
    • Mediator 监听到此 Event,发送通知;
    • 控制器依据通知找到对应的 Command;
    • Command 调用 Proxy(Proxy 又调用 Server 端对象),Proxy 依据执行结果发送相应通知;
    • Mediator 接收到上诉通知,随即把通知中附带的雇员信息赋值给 DataGrid 组件。
  5. 不难理解,我们之所以创建 employees 文件夹就是要把雇员信息相关机能放到此文件下。
    出于此目的我们把显示雇员信息的 DataGrid 组件从 sampleApp.mxml 中分离出来,命名为 EmployeesDataGrid,存储于 employees/view/components 下。
    <?xml version="1.0" encoding="utf-8"?>
    <s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:s="library://ns.adobe.com/flex/spark"
              xmlns:mx="library://ns.adobe.com/flex/mx"
              width="400" x="32" y="25">
    
        <mx:DataGrid id="employeesList" width="400">
            <mx:columns>
                <mx:DataGridColumn headerText="Name"  dataField="name"/>
                <mx:DataGridColumn headerText="Age"   dataField="age"/>
                <mx:DataGridColumn headerText="Email" dataField="email"/>
            </mx:columns>
        </mx:DataGrid>
    </s:VGroup>
  6. 在 sampleApp 中引入 EmployeesDataGrid 组件
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   minWidth="955" minHeight="600"
                   xmlns:view="employees.view.components.*">
    
        <view:EmployeesDataGrid id="employeesDataGrid"/>
    
    </s:Application>
  7. 在 employees 下创建 ApplicationFacade,作为此应用程序的 Facade
    package employees
    {
        import org.puremvc.as3.multicore.patterns.facade.Facade;
        import employees.controller.*;
    
        public class ApplicationFacade extends Facade
        {
            public static const STARTUP:String = 'startup';
    
            public function ApplicationFacade(key:String) {
                super(key);
            }
    
            public static function getInstance(key:String):ApplicationFacade {
                if (instanceMap[key] == null)
                    instanceMap[key] = new ApplicationFacade(key);
    
                return instanceMap[key] as ApplicationFacade;
            }
    
            override protected function initializeController():void {
                super.initializeController();
    
                registerCommand(STARTUP, StartupCommand);
            }
    
            public function startup(app:sampleApp):void {
                sendNotification(STARTUP, app);
            }
        }
    }

    [注:]看到上面的 StartupCommand 了吧,我们稍候创建它,该 Command 主要用于注册 Proxy 和 Mediator。

  8. 在主应用中初始化 Facade,并调用 startup 方法(应该能理解调用此方法的意图吧?)
    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   minWidth="955" minHeight="600"
                   xmlns:view="employees.view.components.*"
                   initialize="facade.startup(this);">
        <fx:Script>
        <![CDATA[
            import employees.ApplicationFacade;
    
            public static const NAME:String = 'sampleApp';
            private var facade:ApplicationFacade = ApplicationFacade.getInstance(NAME);
        ]]>
        </fx:Script>
    
        <view:EmployeesDataGrid id="employeesDataGrid"/>
    
    </s:Application>
  9. 是时候创建 StartupCommand 了
    package employees.controller
    {
        import org.puremvc.as3.multicore.patterns.command.SimpleCommand;
        import org.puremvc.as3.multicore.interfaces.INotification;
    
        public class StartupCommand extends SimpleCommand
        {
            override public function execute(note:INotification):void {
                // @TODO
            }
        }
    }
  10. 至此 pureMVC 已经整合完毕,是不是很简洁?:) 接下来实现雇员信息输出。
  11. 首先在 model 下创建 LoadEmployeesProxy,调用远程对象返回雇员信息
    package employees.model
    {
        import org.puremvc.as3.multicore.patterns.proxy.Proxy;
        import mx.rpc.remoting.RemoteObject;
        import mx.rpc.events.ResultEvent;
        import mx.rpc.events.FaultEvent;
    
        public class LoadEmployeesProxy extends Proxy {
            public static const NAME:String = 'LoadEmployeesProxy';
            public static const LOAD_EMPLOYEES_SUCCESS:String = 'loadEmployeesSuccess';
            public static const LOAD_EMPLOYEES_FAILED:String  = 'loadEmployeesFailed';
    
            private var employeeServiceRO:RemoteObject;
    
            public function LoadEmployeesProxy() {
                super(NAME);
    
                employeeServiceRO = new RemoteObject();
                employeeServiceRO.destination = "employeeServiceDest";
                employeeServiceRO.addEventListener(ResultEvent.RESULT, onResult);
                employeeServiceRO.addEventListener(FaultEvent.FAULT, onFault);
            }
    
            public function load():void {
                employeeServiceRO.getList();
            }
    
            private function onResult(event:ResultEvent):void {
                sendNotification(LOAD_EMPLOYEES_SUCCESS, event.result);
            }
    
            private function onFault(event:FaultEvent):void {
                sendNotification(LOAD_EMPLOYEES_FAILED, event.fault.faultString);
            }
        }
    }
  12. 其次在 view 下创建管理 EmployeesDataGrid 的 Mediator — EmployeesDataGridMediator
    package employees.view
    {
        import org.puremvc.as3.multicore.patterns.mediator.Mediator;
        import org.puremvc.as3.multicore.interfaces.INotification;
    
        import flash.events.Event;
        import mx.controls.Alert;
    
        import employees.ApplicationFacade;
        import employees.model.LoadEmployeesProxy;
        import employees.view.components.EmployeesDataGrid;
    
        public class EmployeesDataGridMediator extends Mediator
        {
            public static const NAME:String = 'EmployeesListMediator';
    
            public function EmployeesDataGridMediator(viewComponent:EmployeesDataGrid) {
                super(NAME, viewComponent);
                employeesDataGrid.addEventListener(EmployeesDataGrid.LOAD_EMPLOYEES,
                                                   onGetEmployees);
            }
    
            protected function onGetEmployees(event:Event):void {
                sendNotification(ApplicationFacade.LOAD_EMPLOYEES);
            }
    
            override public function listNotificationInterests():Array {
                return [
                    LoadEmployeesProxy.LOAD_EMPLOYEES_SUCCESS,
                    LoadEmployeesProxy.LOAD_EMPLOYEES_FAILED
                ];
            }
    
            override public function handleNotification(note:INotification):void {
                switch (note.getName()) {
                    case LoadEmployeesProxy.LOAD_EMPLOYEES_SUCCESS:
                         employeesDataGrid.employeesList.dataProvider = note.getBody();
                         break;
                    case LoadEmployeesProxy.LOAD_EMPLOYEES_FAILED:
                         Alert.show(note.getBody().toString(), 'Error');
                         break;
                }
            }
    
            protected function get employeesDataGrid():EmployeesDataGrid {
                return viewComponent as EmployeesDataGrid;
            }
        }
    }
  13. 把上面创建的 Proxy 和 Mediator 注册到 Model 和 View 中
    package employees.controller
    {
        import org.puremvc.as3.multicore.patterns.command.SimpleCommand;
        import org.puremvc.as3.multicore.interfaces.INotification;
    
        import employees.model.LoadEmployeesProxy;
        import employees.view.EmployeesDataGridMediator;
    
        public class StartupCommand extends SimpleCommand
        {
            override public function execute(note:INotification):void {
                facade.registerProxy(new LoadEmployeesProxy());
    
                var app:sampleApp = note.getBody() as sampleApp;
                facade.registerMediator(new EmployeesDataGridMediator(app.employeesDataGrid));
            }
        }
    }

    [注:]在注册 Mediator 的时候也就确定了它所管理的 Mxml 文件

  14. 在 controller 中创建 LoadEmployeesCommand,用于调用 LoadEmployeesProxy
    package employees.controller
    {
        import org.puremvc.as3.multicore.patterns.command.SimpleCommand;
        import org.puremvc.as3.multicore.interfaces.INotification;
    
        import employees.model.LoadEmployeesProxy;
    
        public class LoadEmployeesCommand extends SimpleCommand
        {
            override public function execute(note:INotification):void {
                var loadEmployeesProxy:LoadEmployeesProxy =
                    facade.retrieveProxy(LoadEmployeesProxy.NAME) as LoadEmployeesProxy;
                loadEmployeesProxy.load();
            }
        }
    }
  15. 把 LoadEmployeesCommand 与事件的对应关系追加到 ApplicationFacade 中
    package employees
    {
        import org.puremvc.as3.multicore.patterns.facade.Facade;
        import employees.controller.*;
    
        public class ApplicationFacade extends Facade
        {
            public static const STARTUP:String = 'startup';
            public static const LOAD_EMPLOYEES:String = 'loadEmployees';
    
            public function ApplicationFacade(key:String) {
                super(key);
            }
    
            public static function getInstance(key:String):ApplicationFacade {
                if (instanceMap[key] == null)
                instanceMap[key] = new ApplicationFacade(key);
    
                return instanceMap[key] as ApplicationFacade;
            }
    
            override protected function initializeController():void {
                super.initializeController();
    
                registerCommand(STARTUP, StartupCommand);
                registerCommand(LOAD_EMPLOYEES, LOADEmployeesCommand);
            }
    
            public function startup(app:sampleApp):void {
                sendNotification(STARTUP, app);
            }
        }
    }
  16. 万事俱备,只需要在 EmployeesDataGrid 创建完毕时触发相应事件
    <?xml version="1.0" encoding="utf-8"?>
    <s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
              xmlns:s="library://ns.adobe.com/flex/spark"
              xmlns:mx="library://ns.adobe.com/flex/mx"
              width="400" x="32" y="25"
              creationComplete="init();">
    
        <fx:Metadata>
            [Event('loadEmployees')]
        </fx:Metadata>
    
        <fx:Script>
        <![CDATA[
            public static const LOAD_EMPLOYEES:String = 'loadEmployees';
    
            public function init():void {
                dispatchEvent(new Event(LOAD_EMPLOYEES, true));
            }
        ]]>
        </fx:Script>
    
        <mx:DataGrid id="employeesList" width="400">
            <mx:columns>
                <mx:DataGridColumn headerText="Name"  dataField="name"/>
                <mx:DataGridColumn headerText="Age"   dataField="age"/>
                <mx:DataGridColumn headerText="Email" dataField="email"/>
            </mx:columns>
        </mx:DataGrid>
    </s:VGroup>
  17. 运行试试吧 :)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本课程总体分为五大部分:一: MVC基本设计理念    首先讲解游戏(包含VR、AR)与软件项目为什么需要有架构与框架的理念。然后讲解游戏引擎、服务端与客户端框架的区分,且梳理分析国内目前主流的游戏客户端架构模式以及优缺点分析。以及PureMVC与StrangeIOC两种MVC开源架构的总体技术刨析。二:PureMVC开源框架插件下载与搭建基础环境。    笔者以开发一个简单的“Hello World”为例,详细讲解PureMVC基础的概念,与框架搭建过程,让学员以较快的时间,学会PureMVC框架的基础理念与应用技巧。三:PureMVC架构设计理念。    基于前面简单版本的开发过程,初步刨析PureMVC架构以“Mediator+事件通知机制”总体设计理念。讲解什么是中介者设计模式(Mediator Pattern),以及事件机制在PureMVC中的基础作用。**分析PureMVC架构基本的开发流程,以及两种不同类型的消息机制。四:开发一款游戏项目(Flappy Birds),集成PureMVC+SUIFW(此框架课程均以发布)两种框架模式,讲解在具体开发一款游戏产品时,如何分析、把握框架与游戏脚本之间的关联关系,如果发挥PureMVC彻底解耦的开发理念。五:基于前面游戏项目的开发,进一步刨析PureMVC架构的高级开发技巧:    1:PureMVC框架类与脚本之间的相互通讯机理。    2:基于PureMVC框架原理,实现游戏项目模型与脚本的彻底分离技术,真正实现美工与研发的同步开发 与无缝对接技术。    3:掌握命令层(即:控制层)中SimpleCommand 与MacroCommand 的区别与具体开发应用技巧。 一、热更新系列(技术含量:中高级):A:《lua热更新技术中级篇》https://edu.csdn.net/course/detail/27087B:《热更新框架设计之Xlua基础视频课程》https://edu.csdn.net/course/detail/27110C:《热更新框架设计之热更流程与热补丁技术》https://edu.csdn.net/course/detail/27118D:《热更新框架设计之客户端热更框架(上)》https://edu.csdn.net/course/detail/27132E:《热更新框架设计之客户端热更框架(中)》https://edu.csdn.net/course/detail/27135F:《热更新框架设计之客户端热更框架(下)》https://edu.csdn.net/course/detail/27136二:框架设计系列(技术含量:中级): A:《游戏UI界面框架设计系列视频课程》https://edu.csdn.net/course/detail/27142B:《Unity客户端框架设计PureMVC篇视频课程(上)》https://edu.csdn.net/course/detail/27172C:《Unity客户端框架设计PureMVC篇视频课程(下)》https://edu.csdn.net/course/detail/27173D:《AssetBundle框架设计_框架篇视频课程》https://edu.csdn.net/course/detail/27169三、Unity脚本从入门到精通(技术含量:初级)A:《C# For Unity系列之入门篇》https://edu.csdn.net/course/detail/4560B:《C# For Unity系列之基础篇》https://edu.csdn.net/course/detail/4595C: 《C# For Unity系列之中级篇》https://edu.csdn.net/course/detail/24422D:《C# For Unity系列之进阶篇》https://edu.csdn.net/course/detail/24465四、虚拟现实(VR)与增强现实(AR):(技术含量:初级)A:《虚拟现实之汽车仿真模拟系统 》https://edu.csdn.net/course/detail/26618五、Unity基础课程系列(技术含量:初级) A:《台球游戏与FlappyBirds—Unity快速入门系列视频课程(第1部)》 https://edu.csdn.net/course/detail/24643B:《太空射击与移动端发布技术-Unity快速入门系列视频课程(第2部)》https://edu.csdn.net/course/detail/24645 C:《Unity ECS(二) 小试牛刀》https://edu.csdn.net/course/detail/27096六、Unity ARPG课程(技术含量:初中级):A:《MMOARPG地下守护神_单机版实战视频课程(上部)》https://edu.csdn.net/course/detail/24965B:《MMOARPG地下守护神_单机版实战视频课程(中部)》https://edu.csdn.net/course/detail/24968C:《MMOARPG地下守护神_单机版实战视频课程(下部)》https://edu.csdn.net/course/detail/24979

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值