论坛首页 Java企业应用论坛

集中式Controller设计 PK 分开式Controller设计

浏览 6419 次
精华帖 (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设计。


欢迎不同观点的人拍砖,请给出你的理由和想法,谢绝谩骂,哈哈。在碰撞中进步

   发表时间:2010-09-19  
Action, DispatchAction
仁者见仁, 智者见智, 爱咋用咋用, 能够保证风格统一就成.
不过搞不明白的是, 增删改跟分页有什么关系?
0 请登录后投票
   发表时间:2010-09-19  
Zahir 写道
Action, DispatchAction
仁者见仁, 智者见智, 爱咋用咋用, 能够保证风格统一就成.
不过搞不明白的是, 增删改跟分页有什么关系?

做的通用flex分页查询只支持单个Command的情况,不支持集中式Controller,就是你说的DispatchAction.和增删改没必然联系,只是flex分页查询引出本文。
0 请登录后投票
   发表时间:2010-09-19  
看看webwork, struts2, 有默认的execute方法(就是分散), 也可以指定(就可以多个方法了,就是集中),springmvc也一样有分散的abstractcontroller, 也有multicontroller支持集中, 这些大框架设计的时候都考虑了两种情况,说明分散和集中差别不会太大,起码说明A对B的指责是不对的,B的设计没什么不对。就我个人而言,我也比较喜欢集中的。
0 请登录后投票
   发表时间:2010-09-19  
我们的项目用的是cairngorm,也是一套MVC的框架。官方推荐的是一个方法一个Command,就像你们同事A的想法一样。
不过我们觉得这样的话产生的类太多了。但是又没有类似于Struts DispatchAction,即通过配置,一个Action处理多个method功能。于是就采用了在一个Command中,通过type,用switch语句来处理不同分支。
这样我们就通过业务模块来划分Command,维护起来也挺方便的。
0 请登录后投票
   发表时间:2010-09-20  
young_suse 写道
我们的项目用的是cairngorm,也是一套MVC的框架。官方推荐的是一个方法一个Command,就像你们同事A的想法一样。
不过我们觉得这样的话产生的类太多了。但是又没有类似于Struts DispatchAction,即通过配置,一个Action处理多个method功能。于是就采用了在一个Command中,通过type,用switch语句来处理不同分支。
这样我们就通过业务模块来划分Command,维护起来也挺方便的。

哈哈,cairngorm是一套adobe官方推出的比较重量级的产品,被我们用puremvc改造中。
0 请登录后投票
   发表时间:2010-09-20  
lewisw 写道
看看webwork, struts2, 有默认的execute方法(就是分散), 也可以指定(就可以多个方法了,就是集中),springmvc也一样有分散的abstractcontroller, 也有multicontroller支持集中, 这些大框架设计的时候都考虑了两种情况,说明分散和集中差别不会太大,起码说明A对B的指责是不对的,B的设计没什么不对。就我个人而言,我也比较喜欢集中的。

就现在的struts2还有spring3中的springmvc来说,通过通配符还有注解的方式,用集中的方式已经非常方便,我想现在几乎已经没有人用分开式Controller设计了。因为一个业务类一个Controller就足以胜任。
0 请登录后投票
   发表时间:2010-09-20   最后修改:2010-09-20
如果从GoF设计模式来说,显然集中式的controller违背了开闭原则。
如果是集中式,你每增加一个方法,都要去改变contoller的代码结构。
如果是分散式,就没有这个问题,扩展多少方法都可以支持。
0 请登录后投票
   发表时间:2010-09-20  
这个貌似你们在开发前的时候 没有沟通好造成的 跟设计没什么关系啊
0 请登录后投票
   发表时间: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已经支持,我们还没用到而已,有知道的通知一声)
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics