Java 思考命令的好或坏习惯
嗯,我看到有一些关于这个的问题和答案,但它们并没有真正让我满意 比如说,我已经编写了一个控制台。这是一个很好的JFrame,有一个输出和一个输入txtField/Area。但是这个控制台不仅应该用于输出,还应该用于运行命令Java 思考命令的好或坏习惯,java,reflection,Java,Reflection,嗯,我看到有一些关于这个的问题和答案,但它们并没有真正让我满意 比如说,我已经编写了一个控制台。这是一个很好的JFrame,有一个输出和一个输入txtField/Area。但是这个控制台不仅应该用于输出,还应该用于运行命令 console.registerCommand(String command, String methodToInvoke, Object invokeObject); 因为我经常需要这个控制台,而且我不想更改控制台的代码,所以我将其编程如下: 控制台有一种注册命令的方法
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()
方法中使用反射,我可以这样做。但是保持代码的一致性有很多好处。我认为,首先要使编写变得简单,减少调试时间并加快以后的更改速度是主要的。