Web前端开发中的MCRV模式(转)
2013-08-20 10:39
274 查看
作者: izujian 来源: baiduux
摘要:针对前端开发中基于ajax的复杂页面开发所面临的代码规模大,难以组织和维护,代码复用性、扩展性和适应性差等问题,本文尝试以MVC思想为 基础,结合Web前端开发中“内容-结构-表现-行为”相分离的开发标准,提出一种将Web页面代码分为视图(View,页面静态部分,包括内容、结构、 表现)、模型(Model,负责数据缓存、数据校验与本地逻辑处理、发起ajax请求)、控制器(Controller,负责用户和系统事件响应、模型和 渲染器调度)、渲染器(Renderer,对视图的渲染,控制器与事件的绑定、数据搜集)的页面开发新模式,并基于此模式提出了一个开发框架原型。
关键字:MCRV设计模式,Javascript,MVC,Web开发标准
1. Web前端开发面临的问题
早期的Web页开发(Web前端开发)中,Web页面较为简单,大多数Web页面的功能仅限于用HTML和简单样式展示静态信息,或向服务器发 送数据,Web页面与用户的交互较少。随着Web的发展,DHTML、CSS、javascript等技术出现,Web页不再仅限于展示静态信息,动态、 交互成为Web页的主流功能之一。与此同时,Web页代码规模也变的较大,页面中的HTML、CSS、Javascript等代码往往混杂在一起,如何很 好的组织这些代码,使Web客户端程序具有很好的结构,易于阅读和维护,成为Web前端开发人员面临的一个难题。在实践中,业界提出了“内容 (Content) - 结构(Structure) - 表现(Presentation) - 行为(Behavior)”相分离的Web页开发标准。在这种标准中,一个Web页代码可以分为如下四个部分:
内容:页面实际要传达的真正信息,包含数据、文档或者图片等。 结构:对内容的划分,使内容更加具有逻辑性,易用性;类似页面的标题、作者、章、节、段落和列表。 表现:用来描述内容外观,称之为“表现”,主要指CSS样式。 行为:行为就是对内容的交互及操作效果;行为控制主要通过javascript实现。
内容 - 结构 - 表现 - 行为(CSPB)开发标准对Web页包含的的代码进行了分类,使代码各个部分得到很好的分离,使Web页初步具有了良好的结构。
随后,Web进入了崭新的Web2.0时代,以Gmail为代表的Web2.0应用大量出现,并且取得很大的成功。这类Web页的典型特征是用 一个基于ajax技术的无刷新的页面完成大量复杂的功能。此类页面包括Web IM、Web Map、Gmail等应用,统称为one-page Web应用。同时,在企业级Web开发中,一个Web页同时完成多个复杂功能的情况也越来越多。在这些复杂Web页应用中, Javascript代码是此类富客户端应用程序的核心,负责与用户的复杂交互和页面展现。One-page Web页面Javascript代码规模往往非常庞大,逻辑复杂,动则千行以上,有时甚至需要一个团队来完成一个页面的开发。如何合理组织大量的 Javascript代码,使之具有良好的扩展性,能够适应需求的变化,使代码易于维护,是广大Web前端开发人员面临的一大挑战。
纵观Web应用程序开发的历史,Web后端开发(PHP、J2EE、ASP.NET)与Web客户端开发的发展过程有一定的相似性,曾面临类似 的问题。最初,Web程序功能简单,代码较少时,所有的控制、逻辑、UI展现代码混杂在一起;随着Web发展,程序规模变大,按原有方式开发出的程序显然 不具有良好的结构,不利于大规模开发和后期维护,也不利于Web开发人员工作和角色的进一步细分,代码复用性差,瓶颈开始出现。Web后端程序设计者的解 决方法是进行代码分类,将控制代码与展现代码开始分离, 于是Web后端开发从所谓的Model1发展到Model2;同时,传统桌面程序设计中的MVC(模型-视图-控制器)设计模式被引入,负责程序数据与逻 辑计算的部分进一步分离出来,形成了Web后端开发中的MVC开发模式。MVC设计模式贯穿了软件工程分而治之的思想,有效解决了Web后端程序设计中的 代码组织和复用问题。采用同一设计模式(MVC)也使代码更容易被他人理解,保证代码可靠性;它使Web开发工作可以细分为业务逻辑开发和UI展现开发。 因此,MVC也利于团队开发。那么,MVC设计思想是否也能应用在前端开发中解决相关问题呢?既然问题具有许多相似性,笔者沿着相同的解决思路来试图解决 前端开发中的代码组织问题。
2. MVC设计模式
在提出本文提出的MCRV设计模式之前,有必要对其所基于的MVC设计模式进行阐述。
MVC这个概念很早之前就被人提起[1],它代表一种设计思想。MVC是Model-View-Conroller的缩写,即模型 - 视图 - 控制器。这种开发模式将一个应用程序分为三个部分,模型(model)实现商业逻辑,提供数据;视图(view)负责向用户呈现界面和接受用户交互;控制 器(controller)则负责响应用户交互请求,对用户请求进行翻译,根据不同的请求调用模型,执行商业逻辑。控制器本质上是一个调度器 (dispatcher),通过其包含的各个方法(action)来执行具体的商业逻辑。MVC各个部件以最小的耦合性协同工作,从而使程序具有良好的可 扩展性和可维护性和复用性。
MVC设计模式最开始被用于桌面程序设计,典型地用于相同的数据需要不同的用户交互界面的设计场景。在经典的MVC设计思想中,控制器负责响应 用户事件,根据事件类型和参数调用模型或改变视图。每个模型对应一个或者多个视图,当模型被控制器调用而得到改变时,模型向所有向其注册过的视图发送通 知,视图根据从模型的中得到的信息改变外观。这种设计模式可以用图1表示。可以看出经典MVC设计模式中Controller、Model 都可以改变视图。
View Code
5. 基于MCRV模式的开发框架原型
5.1 基本设计思想
框架是在一个特定的问题领域内,应用程序的部分设计与实现[2]。框架与设计模式通常是精密结合的。框架规定了应用的体系结构,使基于特定设计 模式的开发能够复用公共代码;反之,框架强调设计复用,框架设计也基本上使用了设计模式,掌握了框架的设计模式可以快速掌握基于框架的应用程序开发。因 此,使用MCRV设计模式进行前端开发时最好有一个与之配合的Javascript框架。
基本设计考虑:
Model、Controller、Renderer组成一个三元组MCR,一个MCR三元组中Controller对象、Model对象和Renderer对象是唯一的。
Model、Controller、Renderer可以初始化和销毁。
Controller、Model、View在需要时可以透明地引用其他对象。
数据与逻辑分离,支持数据本地存储。
一个Web页面可以有多个MCR组,即可以有多个Controller、Model、Renderer三元组分别完成不同的控制、逻辑、展现。这为一个页面逻辑和交互非常复杂时,拆分为多个模块,由多人开发提供了支持。
5.2 基本对象及其关系
下面是一个基于上述考虑的基于MCRV设计模式的Javascript框架原型(以下简称MCRV框架)。
框架的基本对象:MCR、Model、Controller、Renderer、Cache。如图6所示。
![](http://pic001.cnblogs.com/images/2011/24634/2011070917122265.jpg)
图6 基于MCRV模式的框架原型
MCR:控制器(Controller)对象、模型对象(Model)和渲染器对象(Renderer)的复合对象。
- Dispose()方法:执行MCR销毁操作,避免Javascript内存泄露;在页面unload时自动调用;这个方法自动调用Model、Controller和Renderer的dispose()方法。
- model属性:包含的模型。
- controller属性:包含的控制器。
- renderer属性:包含的渲染器。
Model:模型对象。
- init()方法:执行模型初始化。
- dispose()方法:执行对象销毁,释放资源。
- cahce属性:数据的缓存。
Controller:控制器对象
- init()方法:执行控制器初始化。
- dispose()方法:执行对象销毁,释放资源。
- model属性:调度的模型。
- renderer属性:控制的渲染器。
Renderer:渲染器对象
- init()方法:执行渲染器初始化。
- dispose()方法:执行对象销毁,释放资源。
- controller属性:对controller的引用。
Cache:基于key-value的缓存对象
- get()方法:基于键值获取缓存数据。
- set()方法:设置缓存数据。
- remove()方法:删除对应某个键值的缓存。
- size():缓存数量。
5.3 MCRV框架与其他web其他部分的关系
基于MCRV模式的开发框架与Web页面开发其他组成部分的关系可以用图7表示。MCRV框架搭建起了js应用程序整体的结构,提供了应用程序
上下文环境。MCRV框架可以与js组件库、css基础样式库和js业务逻辑组件一起作为应用程序构建的基础,并且它们之间没有依赖关系。尽管应用程序可
以在js基础库(如jQuery)上开发,但是MCRV框架不依赖这些库。
![](http://pic001.cnblogs.com/images/2011/24634/2011070917123089.jpg)
图7 基于MCRV模式的开发框架与其他Web页其他部分的关系
6. 结论
实践表明,MCRV设计模式能够有效解决复杂ajax开发中面临的问题,可以使Web页面代码结构良好,降低Javascript代码的耦合性,提高复用性、适应性和灵活性,使Web页更加易于维护和重构。
参考文献
[1]. Trygve Reenskaug Taskon.Working with objects in the user interfaces.
[2]. J. Van Gurp, J. Bosch.Design, Implementation and Evolution of Object Oriented Frameworks Concepts and Guidelines.pdf.
转载自:http://kb.cnblogs.com/page/107928/
摘要:针对前端开发中基于ajax的复杂页面开发所面临的代码规模大,难以组织和维护,代码复用性、扩展性和适应性差等问题,本文尝试以MVC思想为 基础,结合Web前端开发中“内容-结构-表现-行为”相分离的开发标准,提出一种将Web页面代码分为视图(View,页面静态部分,包括内容、结构、 表现)、模型(Model,负责数据缓存、数据校验与本地逻辑处理、发起ajax请求)、控制器(Controller,负责用户和系统事件响应、模型和 渲染器调度)、渲染器(Renderer,对视图的渲染,控制器与事件的绑定、数据搜集)的页面开发新模式,并基于此模式提出了一个开发框架原型。
关键字:MCRV设计模式,Javascript,MVC,Web开发标准
1. Web前端开发面临的问题
早期的Web页开发(Web前端开发)中,Web页面较为简单,大多数Web页面的功能仅限于用HTML和简单样式展示静态信息,或向服务器发 送数据,Web页面与用户的交互较少。随着Web的发展,DHTML、CSS、javascript等技术出现,Web页不再仅限于展示静态信息,动态、 交互成为Web页的主流功能之一。与此同时,Web页代码规模也变的较大,页面中的HTML、CSS、Javascript等代码往往混杂在一起,如何很 好的组织这些代码,使Web客户端程序具有很好的结构,易于阅读和维护,成为Web前端开发人员面临的一个难题。在实践中,业界提出了“内容 (Content) - 结构(Structure) - 表现(Presentation) - 行为(Behavior)”相分离的Web页开发标准。在这种标准中,一个Web页代码可以分为如下四个部分:
内容:页面实际要传达的真正信息,包含数据、文档或者图片等。 结构:对内容的划分,使内容更加具有逻辑性,易用性;类似页面的标题、作者、章、节、段落和列表。 表现:用来描述内容外观,称之为“表现”,主要指CSS样式。 行为:行为就是对内容的交互及操作效果;行为控制主要通过javascript实现。
内容 - 结构 - 表现 - 行为(CSPB)开发标准对Web页包含的的代码进行了分类,使代码各个部分得到很好的分离,使Web页初步具有了良好的结构。
随后,Web进入了崭新的Web2.0时代,以Gmail为代表的Web2.0应用大量出现,并且取得很大的成功。这类Web页的典型特征是用 一个基于ajax技术的无刷新的页面完成大量复杂的功能。此类页面包括Web IM、Web Map、Gmail等应用,统称为one-page Web应用。同时,在企业级Web开发中,一个Web页同时完成多个复杂功能的情况也越来越多。在这些复杂Web页应用中, Javascript代码是此类富客户端应用程序的核心,负责与用户的复杂交互和页面展现。One-page Web页面Javascript代码规模往往非常庞大,逻辑复杂,动则千行以上,有时甚至需要一个团队来完成一个页面的开发。如何合理组织大量的 Javascript代码,使之具有良好的扩展性,能够适应需求的变化,使代码易于维护,是广大Web前端开发人员面临的一大挑战。
纵观Web应用程序开发的历史,Web后端开发(PHP、J2EE、ASP.NET)与Web客户端开发的发展过程有一定的相似性,曾面临类似 的问题。最初,Web程序功能简单,代码较少时,所有的控制、逻辑、UI展现代码混杂在一起;随着Web发展,程序规模变大,按原有方式开发出的程序显然 不具有良好的结构,不利于大规模开发和后期维护,也不利于Web开发人员工作和角色的进一步细分,代码复用性差,瓶颈开始出现。Web后端程序设计者的解 决方法是进行代码分类,将控制代码与展现代码开始分离, 于是Web后端开发从所谓的Model1发展到Model2;同时,传统桌面程序设计中的MVC(模型-视图-控制器)设计模式被引入,负责程序数据与逻 辑计算的部分进一步分离出来,形成了Web后端开发中的MVC开发模式。MVC设计模式贯穿了软件工程分而治之的思想,有效解决了Web后端程序设计中的 代码组织和复用问题。采用同一设计模式(MVC)也使代码更容易被他人理解,保证代码可靠性;它使Web开发工作可以细分为业务逻辑开发和UI展现开发。 因此,MVC也利于团队开发。那么,MVC设计思想是否也能应用在前端开发中解决相关问题呢?既然问题具有许多相似性,笔者沿着相同的解决思路来试图解决 前端开发中的代码组织问题。
2. MVC设计模式
在提出本文提出的MCRV设计模式之前,有必要对其所基于的MVC设计模式进行阐述。
MVC这个概念很早之前就被人提起[1],它代表一种设计思想。MVC是Model-View-Conroller的缩写,即模型 - 视图 - 控制器。这种开发模式将一个应用程序分为三个部分,模型(model)实现商业逻辑,提供数据;视图(view)负责向用户呈现界面和接受用户交互;控制 器(controller)则负责响应用户交互请求,对用户请求进行翻译,根据不同的请求调用模型,执行商业逻辑。控制器本质上是一个调度器 (dispatcher),通过其包含的各个方法(action)来执行具体的商业逻辑。MVC各个部件以最小的耦合性协同工作,从而使程序具有良好的可 扩展性和可维护性和复用性。
MVC设计模式最开始被用于桌面程序设计,典型地用于相同的数据需要不同的用户交互界面的设计场景。在经典的MVC设计思想中,控制器负责响应 用户事件,根据事件类型和参数调用模型或改变视图。每个模型对应一个或者多个视图,当模型被控制器调用而得到改变时,模型向所有向其注册过的视图发送通 知,视图根据从模型的中得到的信息改变外观。这种设计模式可以用图1表示。可以看出经典MVC设计模式中Controller、Model 都可以改变视图。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=7"/> <title>MCRV 设计模式 Demo</title> <style type="text/css"> /********表现*********/ table{width:100%;border-collapse: collapse;} td{border: 1px solid black;padding: 2px;} #container {width:800px;margin:0px auto;} #tbUsers{margin:20px auto;} #tbUsers th{background-color: navy;color:white;text-align: center;vertical-align: middle;border:1px solid navy} #tbUsers td{text-align: center;} .editCaption{width:100px;text-align: right;} .buttonMargin{margin:0px 20px;} .buttonContainer{text-align: center;vertical-align: middle;height:50px} </style> <script src="./jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script> </head> <body> <!-------结构---------> <div id="container"> <table id="tbUsers"> <thead><th>id</th><th>姓名</th><th>年龄</th><th>修改</th></thead> <tbody/> </table> <div style="display: none;" id="dvEditPanel"> <form id="frmModify" name="frmModify"> <table> <tr> <td class="editCaption"> id: </td> <td><span id="spID"></span></td> </tr> <tr> <td class="editCaption"> 姓名: </td> <td><input type="text" size="20" id="txtName"/></td> </tr> <tr> <td class="editCaption"> 年龄: </td> <td><input type="text" size="20" id="txtAge"/></td> </tr> <tr> <td colspan="2" class="buttonContainer"> <button id="btnSubmitModify" class="buttonMargin" type="button">提交</button> <button id="btnCancelModify" class="buttonMargin" type="button">取消</button> </td> </tr> </table> </form> </div> </div> <script> /***************************行为********************************/ var UserManagerMCR; $(function() { UserManagerMCR=new MCR(UserController,UserModel,UserRenderer); }); /* * MCR 三元组 */ function MCR(Controller,Model,Renderer) { this.controller=new Controller(); this.model=new Model(); this.renderer=new Renderer(); this.controller.model=this.model; this.controller.renderer=this.renderer; this.model.controller=this.controller; this.renderer.controller=this.controller; if(typeofthis.model.init=="function"){ this.model.init(); } if(typeofthis.renderer.init=="function"){ this.renderer.init(); } if(typeofthis.controller.init=="function"){ this.controller.init(); } } /* * 控制器 */ function UserController(){ this.init=function(){ this.initUserList(); } this.initUserList=function(){ var list=this.model.getUserList(); this.renderer.renderUserList(list); } this.beginModify=function(data){ var user=this.model.getUserByID(data.id); this.renderer.showModifyUI(user); } //提交修改 this.submitModify=function(user){ var result=this.model.modifyUser(user); if(result.success){ var list=this.model.getUserList(); this.renderer.renderUIWhenSubmitModifySuccess(list); }else{ alert(result.msg); } } //取消修改 this.cancelModify=function(){ this.renderer.hideModifyUI(); } } /* * 模型 */ function UserModel(){ //模拟的数据,实际应用中经常从服务器获取 this.init=function(){ this.data = [ {id:0,name:"John",age:22}, {id:1,name:"Tom",age:30}, {id:2,name:"Tony",age:25} ]; } //获得用户数据列表 this.getUserList=function(){ //todo ,可能ajax从后端返回 returnthis.data; } //获得用户数据 this.getUserByID=function(id){ var ix; $.each(this.data,function(i,item){if(item["id"]==id ) { ix=i; returnfalse;}}); returnthis.data[ix]; } //修改用户数据 this.modifyUser=function(user){ var result={success:true,msg:"修改成功"}; //todo,验证参数user //todo,修改用户数据 $.each(this.data,function(i,item){ if(item["id"]==user["id"]){ item["name"]=user["name"]; item["age"]=user["age"] returnfalse; } }); return result; } } /* * 渲染器 */ function UserRenderer(){ this.init=function(){ var me=this; $("#btnSubmitModify").click(function(){ var user={id:$("#spID").text(),name:$("#txtName").val(),age:$("#txtAge").val()}; me.controller.submitModify(user); }); $("#btnCancelModify").click(function(){ me.controller.cancelModify(); }); $("#tbUsers .modify").live("click",function(){ var id=$(this).attr("uid"); me.controller.beginModify({"id":id}); }); } this.renderUserList=function(list){ var htm=[]; for(var ix=0;ix<list.length;ix++){ htm.push("<tr><td>"+list[ix]["id"]+"</td>"+"<td>"+list[ix]["name"]+"<td>"+list[ix]["age"]+"</td>" +"<td>"+"<a class='modify' href='javascript:void(0)' uid='"+list[ix]["id"]+"'>修改</a></td>"+"</tr>"); } $("#tbUsers").children("tbody").html(htm.join("")); } this.showModifyUI=function(user){ $("#dvEditPanel").show(); $("#spID").text(user["id"]); $("#txtName").val(user["name"]); $("#txtAge").val(user["age"]); } this.hideModifyUI=function(){ document.frmModify.reset(); $("#dvEditPanel").hide(); } this.renderUIWhenSubmitModifySuccess=function(list){ this.hideModifyUI(); this.renderUserList(list); } } </script> </body> </html>
View Code
5. 基于MCRV模式的开发框架原型
5.1 基本设计思想
框架是在一个特定的问题领域内,应用程序的部分设计与实现[2]。框架与设计模式通常是精密结合的。框架规定了应用的体系结构,使基于特定设计 模式的开发能够复用公共代码;反之,框架强调设计复用,框架设计也基本上使用了设计模式,掌握了框架的设计模式可以快速掌握基于框架的应用程序开发。因 此,使用MCRV设计模式进行前端开发时最好有一个与之配合的Javascript框架。
基本设计考虑:
Model、Controller、Renderer组成一个三元组MCR,一个MCR三元组中Controller对象、Model对象和Renderer对象是唯一的。
Model、Controller、Renderer可以初始化和销毁。
Controller、Model、View在需要时可以透明地引用其他对象。
数据与逻辑分离,支持数据本地存储。
一个Web页面可以有多个MCR组,即可以有多个Controller、Model、Renderer三元组分别完成不同的控制、逻辑、展现。这为一个页面逻辑和交互非常复杂时,拆分为多个模块,由多人开发提供了支持。
5.2 基本对象及其关系
下面是一个基于上述考虑的基于MCRV设计模式的Javascript框架原型(以下简称MCRV框架)。
框架的基本对象:MCR、Model、Controller、Renderer、Cache。如图6所示。
![](http://pic001.cnblogs.com/images/2011/24634/2011070917122265.jpg)
图6 基于MCRV模式的框架原型
MCR:控制器(Controller)对象、模型对象(Model)和渲染器对象(Renderer)的复合对象。
- Dispose()方法:执行MCR销毁操作,避免Javascript内存泄露;在页面unload时自动调用;这个方法自动调用Model、Controller和Renderer的dispose()方法。
- model属性:包含的模型。
- controller属性:包含的控制器。
- renderer属性:包含的渲染器。
Model:模型对象。
- init()方法:执行模型初始化。
- dispose()方法:执行对象销毁,释放资源。
- cahce属性:数据的缓存。
Controller:控制器对象
- init()方法:执行控制器初始化。
- dispose()方法:执行对象销毁,释放资源。
- model属性:调度的模型。
- renderer属性:控制的渲染器。
Renderer:渲染器对象
- init()方法:执行渲染器初始化。
- dispose()方法:执行对象销毁,释放资源。
- controller属性:对controller的引用。
Cache:基于key-value的缓存对象
- get()方法:基于键值获取缓存数据。
- set()方法:设置缓存数据。
- remove()方法:删除对应某个键值的缓存。
- size():缓存数量。
5.3 MCRV框架与其他web其他部分的关系
基于MCRV模式的开发框架与Web页面开发其他组成部分的关系可以用图7表示。MCRV框架搭建起了js应用程序整体的结构,提供了应用程序
上下文环境。MCRV框架可以与js组件库、css基础样式库和js业务逻辑组件一起作为应用程序构建的基础,并且它们之间没有依赖关系。尽管应用程序可
以在js基础库(如jQuery)上开发,但是MCRV框架不依赖这些库。
![](http://pic001.cnblogs.com/images/2011/24634/2011070917123089.jpg)
图7 基于MCRV模式的开发框架与其他Web页其他部分的关系
6. 结论
实践表明,MCRV设计模式能够有效解决复杂ajax开发中面临的问题,可以使Web页面代码结构良好,降低Javascript代码的耦合性,提高复用性、适应性和灵活性,使Web页更加易于维护和重构。
参考文献
[1]. Trygve Reenskaug Taskon.Working with objects in the user interfaces.
[2]. J. Van Gurp, J. Bosch.Design, Implementation and Evolution of Object Oriented Frameworks Concepts and Guidelines.pdf.
转载自:http://kb.cnblogs.com/page/107928/
相关文章推荐
- Web前端开发中的MCRV模式
- MVC 系列:Web前端开发中的MCRV模式
- Web前端开发中的MCRV模式
- Web前端开发中的MCRV模式
- Web前端开发中的MCRV模式
- Web前端开发中的MCRV模式
- Web前端开发中的MCRV模式
- Web前端开发中的MCRV模式
- 前端开发中的MCRV模式
- 前端自动化构建工具Webpack开发模式入门指南 (网上看到的,写得很详细)
- 前端文摘:Web 开发模式演变历史和趋势
- <转>前端开发中的MCRV模式
- Web前端开发JavaScript设计模式 -- 单体模式(The Singleton Pattern)
- 【Web前端】:对前端开发模式的思考
- 【Web前端】:对前端开发模式的思考
- 【转】前端开发中的MCRV模式
- web前端进阶路的开发模式转变
- web前端开发模式
- Web前端设计模式--jQuery验证插件...
- 2012年度最佳Web前端开发工具和框架(下)