8

我想问一下使用匿名类与命名内部类的好习惯是什么?

我正在编写一个 Android 应用程序,其中包括许多 UI 元素(按钮、文本字段等)。对于他们中的许多人,我需要某种侦听器,因此在onCreate应用程序中,我有一堆非常小的匿名类,例如:

someButton.setOnClickListener(
    new View.OnClickListener() {
        public void onClick(View v) {
            // do something...
        }
    }
);

每个这样的匿名类都是 5 到 20 行大 - 足够小,非常适合Java™ 在 Nutshell书中的建议:

一般来说,如果出现以下情况,您应该考虑使用匿名类而不是本地类:

  • 班级的身体很短。
  • 只需要该类的一个实例。
  • 该类在定义后立即使用。
  • 类的名称不会使您的代码更容易理解。

但是,IMO 的问题在于,它onCreate变得相当大,并且通过快速查看代码变得更复杂,难以阅读和理解。它仍然很容易理解,但是太大了。

那么在这种情况下有什么更好的做法 - 有一堆小的内部子类,每个子类都很好地分开,但只使用一次或更好地继续使用匿名类?

4

6 回答 6

8

我不认为有一个明确的答案。两种风格都很好,它真的正是你喜欢的。

另一种选择是拥有

每个 onClick 的内容由单个函数调用,这将使匿名类非常短。IE:

someButton.setOnClickListener(
    new View.OnClickListener() {
        public void onClick(View v) {
            doSomeButtonClick();
        }
    }
);


private void doSomeButtonClick() {
  // do something
}
于 2010-08-26T16:11:32.940 回答
5

将它们重构onCreate()为按通用功能分组的单独方法,以便您拥有逻辑单元。如果 GUI 很复杂,那么稍后会为您提供帮助。

编辑:

此外,由于默认情况下,在匿名类中,代码格式化程序会更多地缩进,因此您的行需要更短,以避免格式化程序将其中断多行,从而使其更长。这通常表明这是提取类并为其命名的好时机。

于 2010-08-26T16:10:31.420 回答
3

我做桌面/摇摆应用程序,但我认为概念是相同的。

我更喜欢在一个类中处理所有事件,因此我创建了一个 Controller 类并在该类中实现我需要的所有侦听器。然后,我在面板上为每种类型的侦听器创建一个方法。它将侦听器添加到面板中需要侦听的每个组件。我将面板作为第一个参数传递给 Controller 类的构造函数,并让它调用面板上的每个添加侦听器方法。然后我在实例化面板时实例化控制器。

这给了我几个好处:

  • 所有的事件处理代码都在一个类中。
  • 事件之间的任何功能交叉都很容易被捕获和处理。
  • 任何受影响的状态都可以在一个类中存储和控制。
  • 所有事件处理代码都与组件布局代码分开。
  • 视图层(面板)对控制器层一无所知。

话虽如此,如果你连接的事件都做简单的事情,并且这些事情不与其他事件发生冲突,那么使用匿名类并没有错。

于 2010-08-26T16:14:29.707 回答
1

我不知道社区是否认为它是最佳实践,但是当这种类变得太大时,我会创建一个包侦听器并在其中创建我的类。如果稍后在您的代码中妨碍您,为什么要使用内部类或匿名类。

但大多数时候,如果这种类变得很大,那是因为你没有足够的委派。也许其他类应该有帮助你的听众更轻的方法。

于 2010-08-26T16:11:40.807 回答
0

正如引用所暗示的,这是主观的。您需要弄清楚对自己来说什么是“非常短”和“更容易理解”,以确定代码大小在什么时候越过界限,从作为匿名类有意义的东西变成有意义的自己的东西单元。

任何人对此给出的任何答案都是基于他们自己对什么是“短”以及不再“短”需要多少行代码的主观衡量。

于 2010-08-26T16:10:01.870 回答
0

将这些项目放在命名类中有几个优点。

第一个是您提到的那个-它将使 onCreate() 方法更加简洁和易于理解。

二是名称要快速识别出哪个逻辑跟哪个按钮走,这样会让代码清零

三是职责分离更容易。如果您决定使用 IoC 模型,您将更容易注入侦听器的命名实现。

于 2010-08-26T16:21:51.097 回答