3

好吧,我看到有一些关于这个的问题和答案,但它们并没有真正让我满意。

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

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

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

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

使用这种方法,我可以在任何地方使用此控制台,而无需更改或继承。

无论何时String command编写,控制台都知道它是一个已注册的关键字,并通过反射执行该方法。

这是一个好的做法还是坏的做法?关于代码样式和性能!还有什么我可以做得更好?

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

编辑

对下面的答案:

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

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

该方法不仅在MenuItem被点击时执行该方法,而且首先创建MenuItem,在其上添加一个调用Method的ActionListener,并将其添加到TrayIcon中。

所以为了使用这个 TrayHelper 我现在可以写:

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

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

编辑 2

好吧,我瞎了。我只是没有意识到如何在没有反射的情况下做到这一点,但它是如此简单。

特别是使用命令模式。

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

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

谢谢 :)

4

1 回答 1

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 命令模式,您可以在此处阅读有关它的更多信息:链接到 WIKIPEDIA

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

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

这并不意味着您需要始终使用它们,但使用久经考验的模式将有助于避免看不见的陷阱。

于 2013-08-07T16:46:06.707 回答