根据Javadocs,嵌套类(在本例中为静态嵌套类)通常用于三件事:
- 对只能一起使用的类进行逻辑分组。
- 增加封装。
- 提高代码的可读性和可维护性。
第 3 点是许多开发人员使用静态嵌套类的原因之一。我们以 Android 开发中的ViewHolder pattern 为例。在ListAdapter 中,我们可以通过管理ViewHolder(或类似名称的内部类)中每个列表元素的内容来轻松缓存列表。在这种情况下,很容易注意到这个特定的ViewHolder 仅适用于这个类,当我们更改这个时,我们不会更改每一个。这意味着我们不需要List1ViewHolder、List2ViewHolder、...、ListNViewHolder。每个List-type 元素都可以有自己的ViewHolder。
第 2 点与这一点不太相关,因为我们正在处理静态内部类(Builder 就是这样)。但在这种情况下,它会阻止内部类的元素被外部类访问。
第 1 点在这里很重要,这就是为什么我把它留到最后。想想你将使用AlertDialog.Builder 的情况。我可以 100% 肯定地保证,您每次使用 AlertDialog.Builder 时,都会在 AlertDialog 的构建/创建/处理中。因此,这意味着AlertDialog.Builder 的每次使用都与AlertDialog 的工作方式相关。 (这在某种程度上与第 3 点相关;在一个文件中维护两个类比将它们分开更容易。)
与第 1 点和第 3 点类似,但也有其自身的特点,即通过将 Builder 保留在 AlertDialog 中,我们不会污染 android.app 包命名空间。我们仍然只在其中保留AlertDialog;但Builder 隐藏在其中。
Android 不是唯一这样做的系统; MotiveWave SDK 也这样做,Adobe Access 和 eBay SDK(我没有链接)也是如此。我也相信Java EE 也使用这种方法。您还将see it often in Enum types,这又是因为第 1 点所述的原因。
现在,您问我们为什么使用AlertDialog.Builder 而不是new AlertDialog(),并从对象而不是构建器构建它。这里的答案与 Java 和其他面向对象编程语言中常见的factory method pattern 相同。值得注意的是(来自维基百科),原因有以下三个:
- 对象的创建会阻止其重用,而无需大量重复代码。
- 创建对象需要访问不应包含在组合类中的信息或资源。
- 生成对象的生命周期管理必须集中进行,以确保应用程序中的行为一致。
这些解释得很好;他们反对代码重复(能够在一个类中处理所有创建功能)、未经授权的访问(糟糕的封装实践)和一致的构造行为。此处未列出的还有code readability。
我怀疑——凭直觉——AlertDialog 是一个非常耗费资源的过程。它会暂停部分操作系统,保持其他部分运行,必须加载系统资源等等。正如this answer 的详细信息,我们不想提供对外部类的直接访问(在这种情况下为AlertDialog)。这允许Builder 正确处理所有资源密集型操作。它还使我们不必处理操作系统开发人员考虑过的深奥情况,但我们没有。
因此,总而言之,这实际上是一种相当普遍的设计模式,但不是具有真正明确定义的含义。相反,它是为了易于使用、理解和可维护性。您提到了对上述设计考虑的担忧;我不会太担心这一点。请记住,静态内部类应该始终仅与它们的外部类相关,你应该没问题。