Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 思考命令的好或坏习惯_Java_Reflection - Fatal编程技术网

Java 思考命令的好或坏习惯

Java 思考命令的好或坏习惯,java,reflection,Java,Reflection,嗯,我看到有一些关于这个的问题和答案,但它们并没有真正让我满意 比如说,我已经编写了一个控制台。这是一个很好的JFrame,有一个输出和一个输入txtField/Area。但是这个控制台不仅应该用于输出,还应该用于运行命令 console.registerCommand(String command, String methodToInvoke, Object invokeObject); 因为我经常需要这个控制台,而且我不想更改控制台的代码,所以我将其编程如下: 控制台有一种注册命令的方法

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

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

console.registerCommand(String command, String methodToInvoke, Object invokeObject);
因为我经常需要这个控制台,而且我不想更改控制台的代码,所以我将其编程如下:

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

console.registerCommand(String command, String methodToInvoke, Object invokeObject);
有了这个方法,我可以在任何地方使用这个控制台,而无需改变或改进

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

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

我还发现,以这种方式使用反射将ActionListeners添加到TrayIcon中的MenuItems中是非常巧妙的

编辑

请回答以下问题:

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

public void addMenuItem(String label, String methodToInvoke, String invokeObject);
此方法不仅在单击MenuItem时执行该方法,而且还首先创建MenuItem,向其添加调用该方法的ActionListener,并将其添加到TrayIcon

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

th.addMenuItem("Exit","exitMethod",this);//executes the exitMethod of
                                         //this class after Menuitem Exit
                                         //was clicked
我真的不明白,除了自己再次写下所有的对象并将它们添加到托盘中之外,我怎么能在没有反射的情况下做到这一点。或者我是瞎子:)

编辑2

好吧,我是瞎的。我只是不知道如何做到这一点,没有反思,但它是如此简单

尤其是命令模式

由于匿名类,我可以这样做,而且我非常喜欢这样编写代码(我总是使用ActionListeners)


谢谢:)

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

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

首先,您有一个界面:

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命令模式,您可以在此处阅读更多信息:

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

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


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

您是否有特定的顾虑?否则,这更多的是讨论而不是问题。你基本上发明了一个穷人的插件架构;我看不出有什么问题。我使用了控制台,感觉它会降低我的表现。不仅是程序的性能,而且是计算机的性能。特别是在更频繁地执行程序后(因为开发,但总是同时执行一个),如果它真的成为问题,以及在什么时候,它会成为问题,那么就会担心性能。除非您在一个循环中从外部重复执行注册的命令数千次,否则我不认为性能会成为一个问题。因此,只要确保invokeObject中运行了任何循环,就不会出现性能问题。在任何情况下,您都需要为每个命令编写一个方法,将其包装到类中就不那么简单了使用命令模式,您可以获得编译时类型安全的代码,而如果您错误地键入方法名称(使用注释可能更安全:)。@LeeMeador:C#中,我认为您只需将
registerCommand
方法a
委托
或lambda表达式交给它即可。有人提醒我,软件模式通常是语言缺陷的修复方法。您不会泄露实现细节,2。“你不再需要反思了?”罗伯塔维我不认为反思是件坏事。如果他想在
execute()
方法中使用反射,我可以这样做。但是保持代码的一致性有很多好处。我认为,首先要使编写变得简单,减少调试时间并加快以后的更改速度是主要的。