Java:我应该在哪里放置匿名侦听器逻辑代码?
我们在工作中争论过在 java 中使用侦听器的最佳实践是什么:侦听器逻辑是否应该保留在匿名类中,或者应该在单独的方法中,例如:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// code here
}
});
或者
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
buttonPressed();
}
});
private void buttonPressed() {
// code here
}
就可读性而言,哪种方式是推荐的方式和可维护性?我更喜欢将代码保留在侦听器内,只有当代码太大时,才将其设为内部类。这里我假设代码在其他地方没有重复。
谢谢。
we had a debate at work about what is the best practice for using listeners in java: whether listener logic should stay in the anonymous class, or it should be in a separate method, for example:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// code here
}
});
or
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
buttonPressed();
}
});
private void buttonPressed() {
// code here
}
which is the recommended way in terms of readability and maintainability? I prefer to keep the code inside the listener and only if gets too large, make it an inner class. Here I assume that the code is not duplicated anywhere else.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我自己制定的规则是:
非常简单,易于遵循并生成或多或少可读的代码。但我不得不承认我从来没有想过你的例子表明了什么。
My self-imposed rule is:
Pretty simple, easy to follow and produces more or less readable code. But then I have to admit that I never even thought of what your example shows.
这个问题在这里得到了部分回答:
对于听众来说是否有更好的实践
This question is partially answered here:
Is there a better practice for listeners
我个人认为,“视情况而定”。如果侦听器仅添加到单个组件中,非常简单并且是 GUI 的组成部分,那么匿名内部类会很好地工作。如果监听器很复杂,会被添加到多个组件中,会有自己独立的状态,那么单独的独立类更好。介于两者之间的是私有内部类。 HTH。
编辑:我的错。我正在回答一个不同的问题——是否为侦听器使用单独的独立类。至于是否将匿名内部类代码保持内联还是在方法中,我同意其他发帖人的观点,这将取决于侦听器代码的大小和复杂性。
In my personal opinion, "it depends". If the listener is only to be added to a single component, is very simple and is an integral part of the GUI, then an anonymous inner class would work well. If the listener is complex, will be added to multiple components, will have its own separate state, then a separate stand alone class is better. In between is the private inner class. HTH.
Edit: My bad. I was answering a different question -- whether or not to use a separate stand-alone class for a listener. As for whether to keep anon inner class code inline vs. in a method, I agree with the other poster, it will depend on the size and complexity of the listener code.
如果需要从匿名内部类之外的任何内容访问方法
buttonPressed()
,那么请使用方法。否则只需将代码放在actionPerformed()
中即可。If the method
buttonPressed()
will ever need to be accessed from anything aside from the anonymous inner class, then use a method. Otherwise simply placing the code withinactionPerformed()
.根据我个人的经验,最好遵循 MVC 模式。这样,就有一个代表模型的单独类,它创建所有相关的操作、操作侦听器等。最好将操作表示为最终类字段,并在构造函数中实例化。
例如:
视图也由一个单独的类表示,该类将模型作为其构造函数参数,实际的按钮实例化发生在其中。例如:
使用这种方法,将 actionPerformed 的逻辑实现为匿名类的一部分非常方便,因为它几乎没有什么可重用的。所有逻辑都封装到控制器中,因此操作实际上充当控制器调用的包装器,以用作按钮的模型。
In my personal experience it is best to follow the MVC pattern. This way there is a separate class representing a model, which creates all relevant actions, action listeners etc. It is preferable that actions are represented as final class fields, which are instantiated in the constructor.
For example:
The view is also represented by a separate class, which takes the model as its constructor parameter, where the actual button instantiation takes place. For example:
With this approach it is quite convenient to implement the logic of actionPerformed as part of the anonymous class since it has very little to be reused. All the logic is encapsulated into the controller, so the actions serve really as a wrapper around the controller call to be used as a model for a button.
是的,这很大程度上取决于您想要做什么。我认为匿名内部类因为两个误区而受到了不好的批评。一是无法重用匿名代码。第二,内存泄漏。但这些问题可以通过简单的方法轻松解决。保存对实例的引用。为了共享代码,只需创建对匿名内部类的引用。
现在您可以在多个组件中重复使用该操作。对于后面的内存泄漏问题,您可以使用该引用来取消注册它,或者第二个也是更简单的选项是 WeakListeners。 WeakListener 的优点是在创建后不需要进行太多管理。
至于风格,我发现匿名侦听器非常方便,并且在某些情况下在处理 Swing 中的线程时更易于阅读,因为它将代码保留在一种方法中(invokeLater、executeInBackground 等)。当您将匿名侦听器委托给实例方法时,我认为它将代码分开,您无法在一个屏幕中读取侦听器之前发生的情况以及与侦听器关联的逻辑。他们往往会被分开,并且很难跟随。
需要注意的是,如果您使用 ActionMap,大多数与键盘监听相关的内存泄漏都会消失。不幸的是,诸如焦点侦听器或向中央系统注册的侦听器之类的事情仍然是一个问题。 (再次强调,WeakListener 在这里很棒)。而且您已经有一个位置来保存每个组件的操作,因此无需创建额外的实例变量来保存它。如果您需要跨两个组件(例如在菜单栏和控件中)重用,请创建一个单独的类。
Yes it depends highly on what you're trying to do. I think Anonymous inner classes have gotten a bad rap because of two myths. One is not being able to reuse anonymous code. And two, memory leaks. But these are easily fixed with a simple approach. Save a reference to the instance. For sharing code just create a reference to the anonymous inner class.
Now you can reuse that action across multiple components. For the later problem of memory leaks you can use that reference to unregister it, or the second and simpler option is WeakListeners. WeakListeners have the advantage of not needing to managed after their creation as much.
As for style I find Anonymous listeners to be quite handy, and in some cases easier to read when dealing with threading in Swing because it keeps your code in one method (invokeLater, executeInBackground, etc). When you anon listener delegates to an instance method I think it separates the code where you can't read what happened prior to the listener and the logic associated with the listener in one screen. They tend to get separated, and it's harder to follow.
Something to be aware of is if you use ActionMaps most of the memory leaks will go away associated with keyboard listening. Unfortunately things like focus listeners or listeners that are registered with central systems are still a problem. (Again WeakListeners are great here). And you already have a place to keep the action with every component so no need to create extra instance variables to hold it. If you need to reuse across two components (say in a menu bar and in a control) create a separate class.