精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-09-18
最后修改:2010-09-18
昨天另外一个team的A过来找我们组的B,谈论通用flex分页的东西(A负责通用分页,我们所有人都是集成一下他的东西)。集成未果,A对B一陈狠批,说什么你怎么这样做,以后后来的人怎么维护等等。B说,怎么可能,我写的注释很清楚,不可能等等。由于涉及到双方的代码改动,B搬出C(也就是我,我是B的头)说:我和C讨论过的,可以采用某某设计等等,于是引出此文。ps:批B相当于批C 二、背景 项目中采用flex+puremvc+blazeDS+spring+hibernate+cxf等技术。我们的争论点在于puremvc中的controller设计。puremvc中的v对应mediator类,c对应command类,m对应vo,通过proxy,用blazeds统一调用分布式的spring应用。不了解的可以自行了解,或者无需了解,因为我们今天的是问题是controller的设计问题(command类)。 三、问题 我们一般在controller设计中有两种方法,一种是集中式设计,一种是分开式设计。flex的command自然也是这样。看看实际的例子,代码不一定对,能看明白就ok. 1.分开式设计: 先看看AddCutoverComand.as(Cutover就是网络割接,联通公司的一种业务类型) package com.xx.controller { import com.xx.model.CutoverProxy; import com.xx.ApplicationFacade; import com.xx.model.vo.CutoverVO; import org.puremvc.as3.interfaces.INotification; import org.puremvc.as3.patterns.command.SimpleCommand; import mx.rpc.IResponder; import mx.rpc.events.FaultEvent; import org.puremvc.as3.interfaces.ICommand; public class AddCutoverCommand extends SimpleCommand { override public function execute( note:INotification ) : void { var cutoverProxy:CutoverProxy = new CutoverProxy(); cutoverProxy.addCutover(); sendNotification(ApplicationFacade.ADD_CUTOVER); } } } 然后自然的有 ModifyCutoverCommand.as,ViewCutoverCommand.as,DeleteCutoverCommand.as,QueryCutoverCommand.as,PublishCutoverCommand.as,ReplyCutoverCommand.as等controller类。 2.我们再来看看集中式的设计: CutoverCommand.as package com.xx.controller { import com.xx.model.CutoverProxy; import com.xx.ApplicationFacade; import com.xx.model.vo.CutoverVO; import org.puremvc.as3.interfaces.INotification; import org.puremvc.as3.patterns.command.SimpleCommand; import mx.rpc.IResponder; import mx.rpc.events.FaultEvent; import org.puremvc.as3.interfaces.ICommand; public class CutoverCommand extends SimpleCommand { var cutoverProxy:CutoverProxy = new CutoverProxy(); override public function execute( note:INotification ) : void { if(type=="add"){ addCutover(note); }else if(type=="publish"){ publish(note); } //很多 if else } void addCutover(...){} void viewCutover(...){} void publish(...){} //other method sendNotification(ApplicationFacade.SOME_CONSTANTS); } } 这样的结果呢就是只有一个该业务相关的Command(Controller) 四、回顾争议的引子 争论的原因是B用的是集中式的controller设计,而A写的通用flex分页只支持分开式的command设计。谁妥协就要改动代码。最后自然是我维护B,我给出了改动的办法: 原来的分页集成代码是: sendNotification(ApplicationFacade.SOME_CONSTANTS,Pagination); actionscript支持动态参数,最后加了个type的参数,分页自然ok了。 sendNotification(ApplicationFacade.SOME_CONSTANTS,Pagination,type); 最后A改动量很少,只加了一个页面的属性,B不用修改代码,原先用分开式Controller设计的同事也不用修改代码。 五、不清楚puremvc ok,你不想看puremvc这些东西,那么想想看我们用过的struts,webwork,springmvc等框架的Controller是不是也有同样的问题。 如分开式设计的AddAction.java,DeleteAction.java,ViewAction.java 集中式设计的BizAction.java 六、我的观点 Struts,Webwork,SpringMVC的项目我之前都有涉及过,我一律用统一式Controller设计,都是一个业务对应一个Controller,里面有自身的一些增删改查的方法。所以我的观点是很明确的,用集中式的设计。 我的理解是: 1.从语义上,Controller做控制的,只是转发一下请求到后台业务类,并不会有太多的操作,犯一着每个method,就新建一个action or command之类的东西。 2.从基于业务角色的角度出发,一个业务一个Controller。 3.维护方面,以后查看修改也方便,不用打开N多类,只在一个类里查看就行。 4.一个method,一个Controller,我觉得设计粒度太细。 5.最后,我就是喜欢集中式Controller设计。 欢迎不同观点的人拍砖,请给出你的理由和想法,谢绝谩骂,哈哈。在碰撞中进步。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-09-19
Action, DispatchAction
仁者见仁, 智者见智, 爱咋用咋用, 能够保证风格统一就成. 不过搞不明白的是, 增删改跟分页有什么关系? |
|
返回顶楼 | |
发表时间:2010-09-19
Zahir 写道 Action, DispatchAction
仁者见仁, 智者见智, 爱咋用咋用, 能够保证风格统一就成. 不过搞不明白的是, 增删改跟分页有什么关系? 做的通用flex分页查询只支持单个Command的情况,不支持集中式Controller,就是你说的DispatchAction.和增删改没必然联系,只是flex分页查询引出本文。 |
|
返回顶楼 | |
发表时间:2010-09-19
看看webwork, struts2, 有默认的execute方法(就是分散), 也可以指定(就可以多个方法了,就是集中),springmvc也一样有分散的abstractcontroller, 也有multicontroller支持集中, 这些大框架设计的时候都考虑了两种情况,说明分散和集中差别不会太大,起码说明A对B的指责是不对的,B的设计没什么不对。就我个人而言,我也比较喜欢集中的。
|
|
返回顶楼 | |
发表时间:2010-09-19
我们的项目用的是cairngorm,也是一套MVC的框架。官方推荐的是一个方法一个Command,就像你们同事A的想法一样。
不过我们觉得这样的话产生的类太多了。但是又没有类似于Struts DispatchAction,即通过配置,一个Action处理多个method功能。于是就采用了在一个Command中,通过type,用switch语句来处理不同分支。 这样我们就通过业务模块来划分Command,维护起来也挺方便的。 |
|
返回顶楼 | |
发表时间:2010-09-20
young_suse 写道 我们的项目用的是cairngorm,也是一套MVC的框架。官方推荐的是一个方法一个Command,就像你们同事A的想法一样。
不过我们觉得这样的话产生的类太多了。但是又没有类似于Struts DispatchAction,即通过配置,一个Action处理多个method功能。于是就采用了在一个Command中,通过type,用switch语句来处理不同分支。 这样我们就通过业务模块来划分Command,维护起来也挺方便的。 哈哈,cairngorm是一套adobe官方推出的比较重量级的产品,被我们用puremvc改造中。 |
|
返回顶楼 | |
发表时间:2010-09-20
lewisw 写道 看看webwork, struts2, 有默认的execute方法(就是分散), 也可以指定(就可以多个方法了,就是集中),springmvc也一样有分散的abstractcontroller, 也有multicontroller支持集中, 这些大框架设计的时候都考虑了两种情况,说明分散和集中差别不会太大,起码说明A对B的指责是不对的,B的设计没什么不对。就我个人而言,我也比较喜欢集中的。
就现在的struts2还有spring3中的springmvc来说,通过通配符还有注解的方式,用集中的方式已经非常方便,我想现在几乎已经没有人用分开式Controller设计了。因为一个业务类一个Controller就足以胜任。 |
|
返回顶楼 | |
发表时间:2010-09-20
最后修改:2010-09-20
如果从GoF设计模式来说,显然集中式的controller违背了开闭原则。
如果是集中式,你每增加一个方法,都要去改变contoller的代码结构。 如果是分散式,就没有这个问题,扩展多少方法都可以支持。 |
|
返回顶楼 | |
发表时间:2010-09-20
这个貌似你们在开发前的时候 没有沟通好造成的 跟设计没什么关系啊
|
|
返回顶楼 | |
发表时间:2010-09-20
jieyuan_cg 写道 如果从GoF设计模式来说,显然集中式的controller违背了开闭原则。
如果是集中式,你每增加一个方法,都要去改变contoller的代码结构。 如果是分散式,就没有这个问题,扩展多少方法都可以支持。 Software entities should be open for extension, but closed for modification,这个就是开闭原则,你说的有一定道理。但我们不要一切唯gof是从。你说的问题在struts2及springmvc3上已经不是问题,只需简单的添加方法就行,exexute的type判断都不用了。 说说puremvc,我们项目中,我不从事flex的一线开发,不知道能不能也像springmvc3,struts2一样的通过配置文件和框架内部处理来解决type判断的问题。 以目前的情况来看,如果采用集中式,那么ApplicationFacade.as中只需注册一个CutoverCommand.as.以后修改的只是CutoverCommand.as.如果采用分开式,那么需要新添加新的Command.as,然后修改ApplicationFacade.as,添加新的注册。所以代码改动不可避免。那么我们来假设puremvc改进后,能支持不用修改ApplicationFacade.as就能动态注册新的Command.as了,type的判断自然也不会再用了。(或许puremvc已经支持,我们还没用到而已,有知道的通知一声) |
|
返回顶楼 | |