Java/Android:匿名本地类与命名类
我想问使用匿名类与命名内部类的良好实践是什么?
我正在编写一个 Android 应用程序,其中包含许多 UI 元素(按钮、文本字段等)。对于他们中的许多人,我需要某种类型的侦听器,因此在应用程序的 onCreate
中,我有一堆非常小的匿名类,例如:
someButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
// do something...
}
}
);
每个这样的匿名类都有 5 - 20 行大 - 足够小并且非常适合《Java™ in a Nutshell》一书的推荐:
一般来说,如果出现以下情况,您应该考虑使用匿名类而不是本地类:
- 该类的主体非常短。
- 只需要该类的一个实例。
- 该类在定义后立即使用。
- 类的名称并不会让您的代码更容易理解。
但问题是,在我看来,onCreate 变得相当大,并且通过快速查看代码,代码变得更加难以阅读和理解。它仍然很容易理解,但太大了。
那么在这种情况下更好的做法是什么 - 有一堆小的内部子类,其中每个子类都很好地分开,但只使用一次,或者更好地继续使用匿名类?
I would like to ask what is the good practice on using anonymous classes vs. named inner classes?
I am writing an Android application, which includes many UI elements (buttons, text fields, etc). For many of them I need some kind of listeners, so in onCreate
of the application I have bunch of quite small anonymous classes like:
someButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
// do something...
}
}
);
Each of of such anonymous class is 5 - 20 lines big - small enough and fits good for recommendations from Java™ in a Nutshell book:
In general, you should consider using an anonymous class instead of a local class if:
- The class has a very short body.
- Only one instance of the class is needed.
- The class is used right after it is defined.
- The name of the class does not make your code any easier to understand.
But the problem, IMO, is that onCreate
becomes quite big and the code becomes more complex to read and understand by quick looking in to it. It is still easy to understand, but simply too big.
So what would be better practice in such case - have bunch of small inner sub-classes, where each of it is nicely separated , but used just once or better keep using anonymous classes instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我认为无论哪种方式都没有明确的答案。两种风格都很好用,这正是您喜欢的。
另一种选择是通过单个函数调用来获取
每个 onClick 的内容,这将使匿名类非常简短。 IE:
I don't think there is a clear answer one way or the other. Both styles work fine, its really just what you prefer.
Another option is to have
the contents of each onClick by a single function call, which will keep the anonymous classes very short. I.e:
将
onCreate()
重构为按常见功能分组的单独方法,以便您拥有逻辑单元。如果 GUI 很复杂,那么它稍后会对您有所帮助。编辑:
另外,由于默认情况下,在匿名类中,代码格式化程序会缩进更多,因此您的行需要更短,以避免格式化程序将其分成几行,从而使其变长。这通常表明现在是提取类并为其命名的好时机。
Refactor the
onCreate()
into separate methods grouped by common functionality so you have logical units. If the GUI is complex then it will help you later.EDIT:
Also, since you are by default indented more by a code formatter when inside an anonymous class your lines need to be shorter to avoid being broken over several lines by the formatter making it longer. This is usually the thing that make it clear that it would be a good time to extract the class and give it a name.
我做桌面/Swing 应用程序,但我认为概念是相同的。
我更喜欢在一个类中处理所有事件,因此我创建一个 Controller 类并在该类中实现我需要的所有侦听器。然后,我在面板上为每种类型的侦听器创建一个方法。它将侦听器添加到面板中需要侦听的每个组件。我将面板作为第一个参数传递给 Controller 类的构造函数,并让它调用面板上的每个添加侦听器方法。然后我在实例化面板时实例化控制器。
这给我带来了几个优点:
话虽这么说,如果您挂接的事件都做简单的事情,并且这些事情不与其他事件冲突,那么使用匿名类并没有错。
I do Desktop/Swing applications, but I think the concepts are the same.
I prefer to handle all of the events in one class, so I create a Controller class and implement all of the listeners I need in that one class. Then, I create a method on the panel for each type of listener. It adds the listener to each component in the panel that it needs to listen to. I pass the panel as the first argument to the Controller class's constructor and have it call each of those add listener methods on the panel. Then I instantiate the controller when I instantiate the panel.
This gives me several advantages:
That being said, if the events you're hooking up all do simple things, and these things don't conflict with other events, then it's not wrong to use anonymous classes.
我不知道社区是否认为这是最佳实践,但是当这种类变得太大时,我创建一个包侦听器并在其中创建我的类。如果内部类或匿名类在稍后的代码中妨碍您,为什么要使用它呢?
但大多数时候,如果这种类变得很大,那是因为你没有足够的委派。也许其他类应该有帮助你的监听器变得更轻的方法。
I don't know if it's considered by the community as a best practice, but when this sort of class gets too big, I create a package listener and create my class in it. Why use inner class or anonymous class if it gets in your way later in your code.
But most of the time, if this kind of class gets big, it's because you didn't delegate enough. Maybe other classes should have methods that help your listener to be lighter.
正如引文所暗示的,这是主观的。您需要自己弄清楚什么才算是“非常短”和“更容易理解”,以确定代码大小在什么时候跨越了界限,从作为匿名类有意义的东西到作为它自己的类有意义的东西单元。
任何人对此给出的任何答案都是基于他们自己对“短”是什么以及不再“短”需要多少行代码的主观衡量。
As the quote suggests, this is something that is subjective. You need to figure out what counts as "very short" and "easier to understand" for yourself, to determine at what point the code size crosses the line from something that makes sense as an anonymous class to something that makes sense to be it's own unit.
Any answers anyone would give you on this is based on their own subjective measures of what "short" is and how many lines of code it takes to no longer be "short".
将这些项目放入命名类中有几个优点。
第一个是你提到的——它将使 onCreate() 方法更加简洁和易于理解。
第二是名称要能够快速识别哪个逻辑对应哪个按钮,这将使代码清晰
。第三是更容易职责分离。如果您决定使用 IoC 模型,那么您将可以更轻松地注入侦听器的命名实现。
You have several advantages to putting these items in named classes.
The first is the one you mention--it will make the onCreate() method more concise and understandable.
The second is that the name should quickly identify which logic goes with which button, which will make the code cleared
The third is easier separation of duties. If you should decide to go to an IoC model, you'll have a much easier time injecting named implementations of the listeners.