一、引子
昨天另外一个team的A过来找我们组的B,谈论通用flex分页的东西(A负责通用分页,我们所有人都是集成一下他的东西)。集成未果,A对B一陈狠批,说什么你怎么这样做,以后后来的人怎么维护等等。B说,怎么可能,我写的注释很清楚,不可能等等。由于涉及到双方的代码改动,B搬出C(也就是我,我是B的头)说:我和C讨论过的,可以采用某某设计等等,于是引出此文。ps:[color=green]批B相当于批C[/color]
二、背景
项目中采用flex+puremvc+blazeDS+spring+hibernate+cxf等技术。我们的[color=green]争论点在于puremvc中的controller设计[/color]。puremvc中的v对应mediator类,[color=green]c对应command类[/color],m对应vo,通过proxy,用blazeds统一调用分布式的spring应用。不了解的可以自行了解,或者无需了解,因为[color=green]我们今天的是问题是controller的设计问题(command类)。[/color]
三、问题
我们一般在[color=green]controller设计中有两种方法,一种是集中式设计,一种是分开式设计。[/color]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);
  	}
}



[color=green]这样的结果呢就是只有一个该业务相关的Command(Controller)[/color]



四、回顾争议的引子


争论的原因是B用的是集中式的controller设计,而A写的通用flex分页只支持分开式的command设计。[color=green]谁妥协就要改动代码。最后自然是我维护B[/color],我给出了改动的办法:


原来的分页集成代码是:


sendNotification(ApplicationFacade.SOME_CONSTANTS,Pagination);



actionscript支持动态参数,最后加了个type的参数,分页自然ok了。


sendNotification(ApplicationFacade.SOME_CONSTANTS,Pagination,type);



最后A改动量很少,只加了一个页面的属性,B不用修改代码,原先用分开式Controller设计的同事也不用修改代码。



五、不清楚puremvc


ok,你不想看puremvc这些东西,那么[color=green]想想看我们用过的struts,webwork,springmvc等框架的Controller[/color]是不是也有同样的问题。


如分开式设计的AddAction.java,DeleteAction.java,ViewAction.java


集中式设计的BizAction.java



六、我的观点


Struts,Webwork,SpringMVC的项目我之前都有涉及过,我一律用统一式Controller设计,都是一个业务对应一个Controller,里面有自身的一些增删改查的方法。所以我的观点是很明确的,用集中式的设计。


我的理解是:


[color=green]1.从语义上,Controller做控制的,只是转发一下请求到后台业务类,并不会有太多的操作,犯一着每个method,就新建一个action or command之类的东西。


2.从基于业务角色的角度出发,一个业务一个Controller。


3.维护方面,以后查看修改也方便,不用打开N多类,只在一个类里查看就行。


4.一个method,一个Controller,我觉得设计粒度太细。


5.最后,我就是喜欢集中式Controller设计。[/color]



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