对命令反思不好或好的做法

时间:2013-08-07 16:38:01

标签: java reflection

嗯,我看到有一些问题和答案,但他们并没有让我满意。

比方说,我编写了一个控制台。这是一个很好的JFrame,带有输出和输入txtField / Area。但是这个控制台不仅应该用于输出,还应该用于运行命令。

因为我经常需要这个控制台,而且我不想改变控制台的代码,所以我这样编程:

控制台有一种注册命令的方法。

console.registerCommand(String command, String methodToInvoke, Object invokeObject);

使用这种方法,我可以在任何地方使用这个控制台而无需改变或吸入。

每当写入String command时,控制台都知道它是已注册的关键字并通过反射执行该方法。

这是一种好的还是坏的做法?关于代码样式和性能!我能做得更好吗?

我还发现以这种方式使用反射将ActionListener添加到TrayIcon中的MenuItems非常简洁。

修改

到下面的答案:

确定命令我会接受这是一种方法。但在Tray示例中,我编写了一个创建TrayIcon的TrayHelper类。在那里,我想添加MenuItems及其ActionListeners但不自己创建每个Object并将它们添加到托盘中。所以我写了这样的方法:

public void addMenuItem(String label, String methodToInvoke, String invokeObject);

此方法不仅在单击MenuItem时执行方法,而且还首先创建MenuItem,向其添加ActionListener以调用Method,并将其添加到TrayIcon。

因此,为了使用这个TrayHelper,我现在可以写:

th.addMenuItem("Exit","exitMethod",this);//executes the exitMethod of
                                         //this class after Menuitem Exit
                                         //was clicked

除了自己再次写入所有对象并将它们添加到托盘之外,我真的没有看到如何在没有反射的情况下做到这一点。或者我是盲目的:)

修改2

好的,我是个盲人。我只是没有意识到如何在没有反射的情况下做到这一点,但它很简单。

特别是使用Command模式。

由于匿名类我可以这样做,我真的很喜欢用这种方式编写代码的方法(我总是用ActionListeners来做)

th.addMenuItem("Test",new Command(){
       public void execute(){
            //do stuff
       }
});

谢谢:)

1 个答案:

答案 0 :(得分:3)

有一种更好的方法可以做到这一点。这有助于隐藏在命令对象内完成的操作。由于您必须更改命令,因此您不必弄乱其他代码。

此外,您可以拥有许多不同的命令,它们可以通过继承或聚合相关联,也可以根据需要相互注入,而且很少有人知道。

首先你有一个界面:

public interface Command {
    void execute();
}

然后您的代码将采用以下方法之一:

console.registerCommand(Command command);

然后你编写了各种实现接口的类并做了一些事情:

public class OneCommand implements Command {
    public void execute() {
        theObject.theMethod(theCommand); // calls what you would have with reflection
    }
}

这是标准的GOF命令模式,你可以在这里阅读更多相关信息:LINK TO WIKIPEDIA

请注意,这种模式以及其他GOF模式于1994年出版在一本书中。作者在许多软件项目中收集了这些最佳实践。那本书正在进行第40次印刷(根据维基百科)。

所有这些都表明,很多人已经找到了很多理由来使用这些软件,多年以及许多编程语言和系统。

这并不意味着你需要经常使用它们,但使用经过试验和测试的模式将有助于避免看不见的陷阱。