请问老师一个关于命令模式的问题

07-10-10 bonepole
public interface command{

public String execute();

}

如果每一个命令都要实现以上接口的话,那文件太多了,我想把相关的命令都放在一个文件中,比如有关用户的命令,把所有要实现的命令就放在用户相关的操作文件中,请问下老师该怎么设计啊?

banq
2007-10-10 14:05
没有明白你的意思。

那文件太多了没有问题,模式就是细化,一个类变成10个类。

bonepole
2007-10-10 15:08
谢谢老师了,可能是我没说明白。

我的意思是想减少单个java文件的数量,因为命令太多了,每一个命令操作都要实现接口,会导致java文件太多而难以管理,能不能把相关的一些操作以方法的形式写在一个文件中,比如用户相关的操作(login,register等)都放在一个UserCommand文件中,就象struts提供了Action的同时又提供DispatchAction

来减少这些相关业务逻辑的action的个数,以便于系统的开发与维护一样。我们没有用struts,自己想用命令模式实现,但又不知道怎么组织。请教老师了,不胜感谢!

rainerWJY
2007-10-11 10:08
如果我没理解错,你的意思是:

public class ConCommand implements Command{

public String execute(){

login();

reg();

}

public void login(){//do something}

public void reg(){//do something}

}

类似这样的?,个人感觉不是不行,但这样做就不够oo了吧,类是靠类名来做主要的区分的。可以用包来划分逻辑区块,但这样写,你的编码就面向修改开放了。而开闭原则我就不重复了。

在灵活性上差一些。个人意见。。

bonepole
2007-10-11 10:45
谢谢rainerWJY了,你说的是对的,这样做的确不够oo,设计也不合理,但java文件太多了也是件烦人的事情啊。

banq
2007-10-11 11:06
>但java文件太多了也是件烦人的事情啊。

这是oo的正常现象,改变你的思维和看法就可以了。否则就不要用OO,没有一个东西只有好处没有坏处。

而且文件太多也不是坏处,举个例子:学开车,老师讲停车就将档位换到一档,这样再起步就直接松离合就可以了,看上去很简单,但是实际问题很多,比如停车时由于情况紧急,有时慌乱中换到三档,再起步这就熄火。我认为应该将步骤再分,停车时换档空档,起步时再向左向前进入一档,虽然多了一个步骤,就象你多几个类文件了,但是就有条不紊了。

文件太多,就用目录包名分类啊,所以,思维和方法很重要。

bonepole
2007-10-11 11:20
恩,谢谢老师的指点,学生会牢记在心的,刚工作经验不足,以后多多学习和实践,在学习和实践中积累经验吧,再次谢谢了!

bosslee
2007-10-11 19:27
可以这样实现。

笨办法。。

public class TestReflectCommand {

public static void main(String[] args){

CommandLoader cl=new DefaultCommandLoader(new DefaultShowCommand());

cl.excute("executeShowList",null);

}

}

public interface CommandLoader {

void excute(String commandName,Object[] argument);

}

public class DefaultCommandLoader implements CommandLoader {

private ShowCommand showCommand;

private HashMap subCommandMap=new HashMap();

public DefaultCommandLoader(ShowCommand showCommand){

this.showCommand=showCommand;

init();

}

private void init() {

Method[] allMethod=this.showCommand.getClass().getMethods();

for(int i=0;i<allMethod.length;i++){

Method m=allMethod;

if(m.getName().startsWith("execute")){

subCommandMap.put(m.getName(), m);

}

}

}

public void excute(String commandName, Object[] argument) {

Method m=(Method) this.subCommandMap.get(commandName);

if(m==null){

throw new NullPointerException("not found command");

}

try{

m.invoke(this.showCommand,argument);

}

catch(Exception e){

throw new RuntimeException("Load command["+m.getName()+"error");

}

}

}

public interface ShowCommand {

public void executeShowList();

public void excuteShowString();

public void executeShowInteger();

public void executeShowLong();

}

public class DefaultShowCommand implements ShowCommand {

public void excuteShowString() {

System.out.println(String.class.getName());

}

public void executeShowInteger() {

System.out.println(Integer.class.getName());

}

public void executeShowList() {

System.out.println(List.class.getName());

}

public void executeShowLong() {

System.out.println(Long.class.getName());

}

}

[该贴被bosslee于2007年10月11日 19:28修改过]

bonepole
2007-10-11 22:00
谢谢楼上的,一个方法的存在总有它的实用价值,你提供给我这个方法我会认真研究一下,谢谢了!!!

banq
2007-10-12 10:52
楼上方法不错。启发了我

其实如果要象struts的dispatchAction那样,可以使用动态代理+方法反射来实现,动态代理如何实现,参考这个帖子的代码:

http://www.jdon.com/jivejdon/thread/18095.html

bonepole
2007-10-12 12:49
程序设计真的是一门艺术,我越来越深刻的体会了,谢谢你们了。

如果还有什么好的方法,希望大家给我指点。

bosslee
2007-10-12 13:36
唉!

建议去读一些原代码。。

这不是一个积极的学习方式。。

刚才的原代码是我分析spring mvc那个模块的时候看到的rod johnson写的一个部分

其实struts本来就没有方法绑定功能。 后来struts也支持这种功能了。。

听说 呵呵

我只分析过struts的早期版本的原代码,就是不支持把一次Request绑定到一个method当中时,所以之后的事情就道听途说。呵呵

知道的struts的本质原理之后,我就没继续研究

这也是 rod johnson为什么要自己实现mvc的初衷。

当然现在是有重复发明轮子的嫌疑。。 呵呵。。 但是我是觉得很难说明对错,因为当时rod johnson发明的时候当时的mvc框架是真的不支持他需要的功能

其实楼主就是不想用if else 对吧?

但是我研究命令模式的时候发现根本就无法避免对象变得很多的事实

所以我也找过很多方法,但是我在读spring原代码的时候就发现了这种解决方法,在访问者模式当中也可以用这个方法实现的。

这样的话本质上是可以减少对象变多的事情,但是你要相应的付出代价,那就是性能。

但是我觉得有的时候不一定非要oo思想来编成,有时候也可以放弃那种想法,编成的时候尽量把自己局限在一个规则当中这是好的,这样你会发现一

时间之后你的功力有长足的进步,但是我的思想是,觉得实在不行的时候可以想这里真的非要这样实现吗? 要看你的了?

这是我的经验。。 废话多了。。

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

boyszz
2007-10-13 16:12
public class UserCommand {
    public static class LoginCommand implements Command {
        public String execute() {
           //your implements
        }
    }

    public static class LogoutCommand implements Command {
        public String execute() {
           //your implements
        }
    }
}
<p>

可以减少文件数量

[该贴被boyszz于2007年10月13日 16:13修改过]

bonepole
2007-10-13 16:39
谢谢楼上的朋友,你采用静态内引类的方式实现是一个好的办法,我也想这样实现,但不知道这样的实现有没有问题,都这么编码总觉得怪怪的。

bonepole
2007-10-13 16:46
我觉的用以上方法实现比bosslee兄弟的要好些,因为只需要提供一个Command接口,而bosslee兄弟的方法对不同的命令要定义不同的接口,比如UserCommand接口,ManagerCommand接口等,不知道说的正确不,我是这样理解。谢谢boyszz兄弟提供的方法。

猜你喜欢
3Go 1 2 3 下一页