恩?

楼上的那段代码,看着不太明白是否可以写出测试代码?

谢谢

楼主遇到的问题应该是命令接口里只定义了一个方法,每个命令对象都只简单实现了这一个方法而已,一旦每个命令对象的方法实现很简单,就会造成造成命令对象过小.可能只有寥寥几行代码。
通过内部静态类虽然可以减少文件数量,但无法减少类的数量。类膨胀是命令模式带来的。无法避免。
bosslee提供的方案是让一个命令对象中的一个命令(即命令接口里定义的某一方法)有多种功能,相当于一个转发功能。有可能是被楼主的例子给误导了。
命令模式应该是多个不同的对象间拥有相同的方法,却有不同的实现(例如门、窗、空调、电视都有一个打开的方法open(),但其实现是完全不同的)。而楼主给的例子看上去像是在描述同一个对象有不同的方法。

恩!

我理解你在说什么。

呵呵!

我想知道,这个测试代码是否可以写出来,我想整理这种方法

谢谢

>命令模式应该是多个不同的对象间拥有相同的方法,却有不同的实现(例如门、窗、空调、电视都有一个打开的方法open(),但其实现是完全不同的)。

这句话让我重新理解了命令模式。。。。。。。

我的天,那么多"b",我都搞不清楚是几个人,都是"b"开始的名字,本来讨论的模式就搞人,你们取的名字有相似,让人头大啊,哈哈。

楼上两位解答都很不错,从理论上都是答案,只是实现途径不一样而已。

这里我想提醒的是,也许我们已经陷入一个误区:

楼主由于没有给出他使用Command模式的场景或者说环境,又要克服Command模式缺点,那一般就不用正常Command模式来实现(楼上答案除外),其实Command模式是套在业务逻辑方法外面的一个套子,这个套子不只是Command模式一种套子,可以用其他模式来做这个套子,我在以前一篇"J2EE中几种业务代理模式的实现和比较"写了这样几个套子模式的比较。

http://www.jdon.com/artichect/businessproxy.htm

最后,我说要说的是:最好的解决方式就是不用套子,也就是将业务逻辑通过动态代理+方法反射直接暴露给客户端,以本例子说明:

就是将DefaultShowCommand 中的命令方法内容,如:
public void excuteShowString() {
System.out.println(String.class.getName());
}

其中 System.out.println(String.class.getName());就是真正业务逻辑直接暴露给客户端,不要使用Command模式,更不要在上面加一个excuteShowString这样的套子方法。

不知我的描述是否清楚。其实这里就有导出为什么使用Spring/jdonFramework这样业务框架的好处,原来SUN的Petstore就是使用Command 模式为业务层做了个套子,结果导致类个数增多(也是楼主讨厌的那样),导致复杂性。

以上也是各位深入讨论使我联想写这个帖子,希望没有跑题。

[该贴被banq于2007年10月13日 21:20修改过]

呵呵!

恩! 怎么说呢。。 我就是想知道,上面那个客户端应该怎么写

仅此而已。。 没有别的。。

其实早就发现了楼主的问题。

但是我发现有这种代码贴出来,既然贴出来了,当然要研究一下。呵呵

希望给与回答 谢谢

Bang:
我知道,我也一直是那么做的,那天楼主提出了疑问,我就想起了那段代码就写了。。 呵呵。。

我在拜读你的论坛代码的时候我也发现了你的思想,而且根我所想的和一样。

恩。。 其实刚才那种代码在控制层当中有很好的用处,就像有一个登陆请求的话,longin.jsp这个时候把路径,loing和UserLogin方法绑定让他来处理基本的Request当中的参数,然后把这个参数转换成领域对象然后让领域服务来处理业务。。

其实最近又一个问题想请教的。。 呵呵

不知道什么时候你有时间。。


多谢bosslee,非常高兴能够和你讨论,可开新帖。

关于本专题,我又想了一下,之所以使用Command模式,是因为请求可以被打包成对象(如字符对象)在客户端和被调用者传递,这也就是说,客户端和被调用者可以不是同一个系统,例如浏览器客户端URL对服务器端命令的调用,客户端的环境是IE浏览器等Html环境,请求被打包成字符串,例如form的action值,如action="/serviceAction.do",就是通过直接服务器端命令serviceAction的execute方法。

这就是传统命令模式的所用之处。struts的dispatchAction将多个方法和在一起,是采取bosslee 那种方法反射来完成的。

以上都很好,我想说的是进一步话题:dispatchAction中不是还要调用业务层Service的方法吗?比如serviceAction的xxxx方法调用业务层testService的xxxxx业务方法,我们可以连dispatchAction都不要,直接将testService的xxxxx业务方法暴露给浏览器客户端。

那么浏览器客户端调用形式是什么?如下:
serviceAction.do?method=abcd
这样,就会直接调用testService的abcd方法,无需每次都写dispatchAction,也就是dispatchAction都不要了。业务方法也可以直接暴露给非java客户端,无需Command模式做套子,多此一举。

这个功能已经在JdonFramework中实现,详细说明:
http://www.jdon.com/jdonframework/new.htm

可下载下面应用包的struts+jdon+jdbc案例测试:
http://www.jdon.com/jdonframework/app.htmsimple

不好意思有些做广告嫌疑,不过只是想起到抛砖引玉的效果,也欢迎大家结合自己的产品谈设计,不要有明显广告就可以。

罗嗦了这么多,这个帖子其实回答了楼主的问题:使用Command模式,但是嫌类太多,要学习dispatachAction那样多个方法放在一个类中,我的回答就是:那就不要用command模式,dispatachAction甚至也无需学习,dispatachAction也不要用,把command或dispatachAction封装的东东直接暴露给客户端,直接Show自己。这不是一种更简单的方法吗?

bosslee上贴说:那种代码在控制层当中有很好的用处,就像有一个登陆请求的话,longin.jsp这个时候把路径,loing和UserLogin方法绑定让他来处理基本的Request当中的参数,然后把这个参数转换成领域对象然后让领域服务来处理业务

这点我同意,我不是故意抬杠,其实从request处理参数转换成领域对象这件事情也可以不必做,因为request的参数都已经封装在ActionForm这样的界面对象中,ActionForm转换领域对象工作也可以放在框架中,对于login这样特例,更是可以交给容器或框架来实现,对于其他特例一定要和request打交道,容器框架又无法实现的情况比较少了。

就象RoR把业务层和控制层混合一起达到快速开发,我们为什么不可以把控制层压缩,重点转移业务层中以提高快速开发呢?,让控制层只留一个配置去定义,这样,我们就可以专心业务层业务编写,而不必烦恼到底这个功能在控制层实现还是放在业务层呢?


[该贴被banq于2007年10月13日 23:00修改过]

> 关于本专题,我又想了一下,之所以使用Command模式,是因为请求可以被打包成对象(如字符对象)在客户端和被调用者传递

我的情况就是这样的,所以选择了命令模式,谢谢banq老师给我们这些新手提供了这么多好的方法。

Bang :

呵呵 你真热情。。

我以前接的第一个项目就是那样写的。。

那个项目的代码,现在还在我的脑海中。

因为那是我的第一个项目

那时候新手,根本就不懂,我们是为了扩展他们一些功能而进去的

他那里的代码就是那样

public class RequestTest extends HttpServlet{


/**
*
*
* @author boytear
*
*/
private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException{
doPost(req,res);
}

public void doPot(HttpServletRequest req,HttpServletResponse res){

Method[] method=this.getClass().getMethods();
String methodName=req.getParameter("methodName");
for(int i=0;i<method.length;i++){

if(method.getName().equalsIgnoreCase(methodName)){
try {
method.invoke(this,new Object[]{req,res});
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
}

其余的都继承这个类。。
那时候是三年前,但是那个程序我们参加的时候开始运行了。好像写了有1,2年。 我觉得写那个人是高手,后来一起写项目,相互认识了,那个人的思想很前卫。

or-mapping那一块好像也是他自己实现的,那时候根本没有什么框架

当时蔡鸟的我好崇拜他的,呵呵。

呵呵。。 还有郑重声明,我可不是新手,让我的教授听见了,要扣我工资的哦。。
呵呵

在资本主义社会工作,不可以太谦虚地哦。。

谅解一下 呵呵

[该贴被bosslee于2007年10月13日 23:27修改过]

关于这个问题我觉的最重要的是要搞清楚在什么情况下设计应该考虑使用命令模式,也就是它的使用场合,这个可能与具体环境和情况用关,但模式的选择方案和使用应该都是可以被合理解释和理解的,一般情况下能确切的找到他们的合适使用地点,大家都在什么样的情况下使用命令模式啊?

>大家都在什么样的情况下使用命令模式啊
当存在客户端和服务器两个分离客体进行调用时,这时会首先想到用命令模式,命令模式是一个事件模式,也就是说发生事件时才可能需要用到。

一般我们做JavaEE,都是在现成框架下工作,比如MVC框架都已经整合入命令模式,我们只要完成Command实现子类就可以,但是首先我们必须知道这里有命令模式,否则就是实现command子类都不知道什么模式,在框架下工作,虽然不需要我们决定是否选用命令模式,但是我们必须知道什么是命令模式,当然后者难度要小一些。

那么什么情况下决定是否选用命令模式?说通俗一些,如果你的客户端不支持struts这样的浏览器技术,比如移动客户端 专用胖客户端(这里也有框架实现)。

总之命令模式是一个比较底层架构的事件模式,普通信息系统程序员不太容易遇到是否选用命令模式这样高难度架构设计问题。

struts框架中的Action和DispatchAction用到了命令模式了

老师,我现在感觉面向对象的分析和设计技能真不是一朝一夕能够学到的,也不是看几本面向对象的书可以掌握的,就是掌握了书上的例题,系统变了,需求变了,一切就变了。这是一种哲学思想,一种能力,一种创造力,一种对客观世界的理解和认识能力,一种对软件世界的认知能力。分析和设计方法只是具体设计过程中基础的指导原则,就是掌握了这些指导原则有时候都不知道在什么时候,什么地方去运用它。一句话,做任何事情除了积累真是需要天赋的!

我现在发现自己真没有做软件的天赋。。。。。。。。

command模式不是简单的execute,还要考虑undo和redo.
所有command放在一个类中,undo和redo非常难实现.
[该贴被hwrzsl于2007-10-20 19:58修改过]

本人菜鸟,潜水多年。
感觉你这个问题跟我前阵子遇到的差不多,下面说说我的解决方案,可能比较笨的办法,如果各位有建议,在下感谢万分。

我遇到的问题是在做Service层时遇到的。Service是由不同的方法组成,每个方法都代表一个具体业务逻辑。而且一个业务逻辑还有可能被别的业务所调用。问题在管理每个方法的事务上。刚开始的设计是靠不同的基类来区分事务,跟搂主的问题一样,基类决定了子类只能有一个方法实现。问题就是文件数目的增多。
后来决定用Aop解决这个问题,Spring是解决这个问题的一个办法,但是我不太喜欢把耦合都集中在XML中,所以就借助Proxy和Annotation技术自己做了个Aop代理。靠在Service接口里的方法前加自定义的注释来解决动态加载事务的功能。个人感觉方法还算比较好,耦合度很低。
不知道各位还有什么更好的解决方案,希望给我点建议。

联系方式:
skype: yuyong88
msn: yuyong22@hotmail.com
很高兴认识各位。
[该贴被yuyong于2008-02-27 17:15修改过]