企业管理及信息化解决方案;--因为专注,所以专业!
客服热线:028-86272612
成都蓝源 -> > Ext资讯 -> 详细内容
Deft JS:通过依赖注入实现低耦合MVC
时间: 2012-05-21    来源:

 

      应用才刚刚部署?作为经验丰富的软件开发人员,都知道不用多久就要做重大的用户界面修改。无论如何深思熟虑,如何通过需求分析和设计与客户达成一致,能避免修改的设计几乎没有。真正行之有效的软件,是能以少成本适应不断变化的用户需求的软件。

      那么……如何架构软件,才能迅速实现用户界面的变化,而不用破坏底层的基础业务逻辑呢?

模型 视图 控制器(MVC)

      在代码中应用架构的起始阶段,重点是将应用划分成不同的管理单元,每个管理单元负责一个应用事务。为此,大多数应用采用模型-视图-控制器架构模式。实现这种模式有多种方式,软件开发专家马丁将这些实现模式经过收集和整理,并编录在这里

 

      通常,一个MVC架构包括:

  • 模型:描述和管理应用数据的行为和状态,并根据请求做成相应的响应或修改状态。
  • 视图:将模型数据显示给用户,接受用户输入,并监听用户行为,如单击或选择操作。
  • 控制器:模型和视图之间的中介,监听用户行为并相应的在模型上执行操作,然后刷新视图以反应模型的变化。

      通过控制器通过观察业务逻辑分离的用户接口组件和布局(视图),然后触发业务逻辑更新应用数据,可使应用更好的适应不断变化的业务需求。

Deft JS MVC

     Deft JS是增加的Sencha MVC框架,主要包括:

  • 模型使用通常(faceless)的业务逻辑组件,如Ext.data.Store、Ext.Data.Model。
  • 视图可使用Ext JS这个丰富的开发包或Sencha Touch内的容器和组件。
  • 控制器则通过创建继承于Deft.mv.ViewController对象的特定视图控制实现。

Deft JS视图控制器

      通常,一个视图就是一个包含多个组件组成的容器。一个视图控制是yield轻量级的控制器,负责管理指定视图的及其子组件的状态,监听视图及其子组件的事 件,并响应用户操作,并委托工作以便注入业务模型和服务(如Ext.data.Stores、Ext.data.Models等)。

      在Deft JS,一个视图通常是一个Ext JS类的填充了子组件的子类。视图定义要混入Deft.mixin.Controllable对象,同时要声明相关的视图控制器类名。每一个视图,都要创 建一个对应的,从Deft.mvc.ViewController扩展的视图控制器类。这个特定的视图控制需要设置其引用相关的视图组件,并注册视图控制 器的方法来处理视图组件的事件。

       Deft JS视图控制器及混入的Controllable的主要功能是:

  • 提供类声明驱动以关键视图和视图控制器。
  • 明确控制器类的作用,即控制指定的视图。
  • 支持指定视图的多个独立实例,每一个视图都有其唯一的视图控制器实例。
  • 通过自动创建和销毁视图控制器及其相关的视图,以减少内存。
  • 为引用视图组件和为视图控制器的方法注册监听事件 提供简洁的配置。
  • 在集成的视图的生命周期内,运行移除或销毁视图控制器。
  • 自动删除视图、视图组件引用和事件监听,以简化清理操作。

Deft JS依赖注入


      许多模型、视图和控制器对象都不是独立的(self-contained)。它们会引用或委托一些工作给其它对象。这些被引用的对象就会成为依赖。通常,你可以显式地创建这些依赖的实例或者从服务定位器手动请求它们。

      在应用组件之间鼓励实现低耦合,Deft JS包含一个轻量级用于依赖注入的反转控制(IOC)。当执行IOC主体时,可以通过类声明列表代替手动创建或获取依赖类。当类需要延迟实例化,IOC容 器会负责处理这些依赖所需的正确的对象实例,并在运行时将它们注入类。

      有了IOC,在类中就不再需要创建依赖类,或者明确定义这些依赖类。此外,它不再需要绑定依赖类的特定实现。通过提供预期的API,可以配置IOC容器注入一个完全不同的实现。

      因此,你可以很容易的通过配置IOC容器来模拟任何的依赖类版本来测试你的类。你也可以创建多个不同的应用,在每个应用的IOC容器内配置使用不同的依赖 类实现,如Store和Proxy。例如,可配置使用静态JSON文件驱动的模拟Store和Proxy;也可以配置为通过JSONP使用 production服务的Store和Proxy。

      Deft JS IoC容器及其混入的Injectable的主要功能包括:

  • 提供类解释驱动依赖注入
  • 通过用户自定义标识映射依赖
  • 解决类实例、工厂模式或值的依赖关系
  • 支持单件模式、类实例原型的分解和工厂模式的依赖关系
  • 提供延迟渲染的实例依赖关系
  • 在Ext JS类的构造函数执行之前,在配置项和属性注入依赖

示例

设想在一个联系人管理应用的视图内包含yield联系人Grid:

[javascript] view plaincopy
  1. Ext.define( 'ContactsApp.view.ContactGridView',  
  2.     extend: 'Ext.container.Container',  
  3.     mixins: [ 'Deft.mixin.Controllable''Deft.mixin.Injectable' ],  
  4.     inject: [ 'contactStore' ],  
  5.     controller: 'ContactsApp.controller.ContactGridViewController',  
  6.    
  7.     config: {  
  8.         contactStore: null  
  9.     },  
  10.     ...  
  11.     initComponent: function() {  
  12.         this.items = [{  
  13.             itemId: 'contactsGrid',  
  14.             xtype: 'gridpanel',  
  15.             store: this.getContactStore(),  
  16.             ...,  
  17.             bbar: Ext.create( 'Ext.PagingToolbar', {  
  18.                 store: this.getContactStore(),  
  19.                 ...  
  20.             })  
  21.         },  
  22.         ...  
  23.         {  
  24.             xtype: 'container',  
  25.             ...  
  26.             items: [{  
  27.                 itemId: 'editButton',  
  28.                 xtype: 'button',  
  29.                 text: 'Edit'  
  30.             }],  
  31.             ...  
  32.         }];  
  33.     }  
  34. );  

      视图类的定义通过混入Deft.mixin.Injectable,及它的依赖通过“inject”声明,已经具备注入功能。

      当视图通过Ext.create()或 Ext.widget()实例化的时候,Ioc容器将处理“contactStore”的依赖和注入相关的值到“contactStore”的配置。产生的getContactStore()方法将会返回注入值。

      另外,视图类通过混入Deft.mixin.Controllable,及使用“controller”声明控制,具备了控制功能。

      当视图实例化的时候,指定的视图控制器会被创建及被配置引用视图。当视图销毁的时候,视图控制器也会被销毁。

[javascript] view plaincopy
  1. Ext.define( 'ContactsApp.controller.ContactGridViewController',  
  2.     extend: 'Deft.mvc.ViewController',  
  3.     mixins: [ 'Deft.mixin.Injectable' ],  
  4.     inject: [ 'contactStore' ],  
  5.    
  6.     config: {  
  7.         contactStore: null  
  8.     },  
  9.    
  10.     control: {  
  11.         contactsGrid: {  
  12.             click: 'onContactsGridClick'  
  13.         }  
  14.         editButton: {  
  15.             click: 'onEditButtonClick'  
  16.         }  
  17.     },  
  18.     ...  
  19.     destroy: function() {  
  20.        if (this.hasUnsavedChanges) {  
  21.            // cancel destruction  
  22.            return false;  
  23.        }  
  24.        // allow destruction  
  25.        return this.callParent( arguments );  
  26.     },  
  27.     ...  
  28.     onEditButtonClick: function () {  
  29.         this.getEditButton.setDisabled( false );  
  30.     },  
  31.    
  32.     onContactsGridClick: function () {  
  33.         // add a ContactEditorView to the TabPanel for the selected item  
  34.         ...  
  35.     },  
  36. );  


      视图控制器扩展自抽象基类Deft.mvc.ViewController,它提供了一个“control”配置项用于简化视图组件的访问器的创建及为它们绑定事件。

 

      示例中,Gird和按钮可通过itemId(也支持自定义选择器)引用,它们的单击事件句柄则定义为视图控制器的方法。两个访问器函数会自动创 建:getContactsGrid() 和getEditButton()。当视图被销毁时,视图控制器的destroy方法会被调用,通过它可以阻止视图销毁。如果该方法返回true,视图将 被销毁,所有在视图控制器通过“control”定义创建的引用和监听事件会自动被删除。

      Ioc容器通常在主应用的javascript文件中的Ext.onReady()内定义,调用Deft.Injector.configure()方法。

[javascript] view plaincopy
  1. Ext.onReady( function () {  
  2.     Deft.Injector.configure({  
  3.         contactStore: 'ContactsApp.store.ContactStore'  
  4.         // contactStore: 'ContactsApp.store.MockContactStore'  
  5.     });  
  6. });  

      在示例中,Deft JS Ioc容器已配置执行请求ContactsApp.store.ContactStore的单件模式实例“contactStore”。注释行显示如何简单的使用指定模拟类来代替它。



关于Deft JS

      Deft JS是一个使用MIT协议,扩展自Ext JS和Sencha Touch API的开源框架,它提供:

  • 通过IOC容器实现低耦合度和依赖注入。
  • 通过替代模型视图控制器实现灵活的面向组件的架构
  • 优雅的异步操作链和使用Promises及Deferreds的数据处理。

Created by a team of software architects working at the innovative digital solutions agency Universal Mind, Deft JS leverages best practices and proven patterns refined over years of delivering cutting edge solutions across a wide range of platforms and devices.

 

原文地址:Deft JS: Loosely Coupled MVC through Dependency Injection

中文翻译:http://blog.csdn.net/tianxiaode/article/details/7576638



3.62K