为什么在Android中使用"AlertDialog.Builder"而不是"AlertDialogBu​​ilder"的奇怪命名约定

How*_*ard 12 android android-alertdialog

为什么不

AlertDialogBuilder builder = new  AlertDialogBuilder(this);
builder.setTitle("foo");
Run Code Online (Sandbox Code Playgroud)

代替

AlertDialog.Builder builder = new  AlertDialog.Builder(this);
builder.setTitle("foo");
Run Code Online (Sandbox Code Playgroud)

更新:我想知道这种写作/组织背后的原因

Eri*_*ric 24

根据Javadocs,嵌套类(在本例中,静态嵌套类)通常用于三件事:

  1. 逻辑分组只能一起使用的类.
  2. 增加封装.
  3. 提高代码的可读性和可维护性.

Point#3是很多开发人员使用静态嵌套类的原因之一.例如,让我们看一下Android开发中的ViewHolder模式.在a中ListAdapter,我们可以通过管理ViewHolder(或类似命名的内部类)中每个列表元素的内容来轻松地缓存列表.在这种情况下,很容易注意到这个特定ViewHolder仅适用于这个类,当我们改变这个类时,我们不会改变每个类.这意味着我们不需要List1ViewHolder,List2ViewHolder,..., ListNViewHolder.每个List元素都可以有自己的元素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的软件开发工具包(我缺少链接).我也相信Java EE也使用这种方法.你也会经常在Enum类型中看到它,而这又是因为第1点所涵盖的原因.

现在,您问我们为什么使用AlertDialog.Builder而不是new AlertDialog()从对象而不是构建器构建它.这里的答案与Java和其他面向对象编程语言中常见的工厂方法模式相同.值得注意的是(来自维基百科),有三个原因:

  1. 对象的创建阻止了它的重用,而没有重复的代码重复.
  2. 创建对象需要访问不应包含在撰写类中的信息或资源.
  3. 必须集中生成对象的生命周期管理,以确保应用程序内的一致行为.

这些解释得很好; 他们反对代码重复(能够处理一个类中的所有创建功能),未经授权的访问(错误的封装实践)以及一致的构造行为.此处未列出的是代码可读性.

我怀疑 - 在预感 - 这AlertDialog是一个非常资源紧张的过程.它会暂停部分操作系统,让其他操作系统保持运行,必须加载系统资源等等.由于此答案详细说明,我们不希望提供对外部类的直接访问(AlertDialog在本例中).这允许Builder正确处理所有资源密集型操作.它还使我们不必处理操作系统开发人员考虑的深奥情况,但我们没有.

因此,总而言之,这实际上是一种相当普遍的设计模式,而不是具有真正明确定义含义的设计模式.相反,它是为了易于使用,理解和可维护性.您提到了对上述设计考虑因素的担忧; 我不会太担心.请记住,静态内部类应始终仅与其外部类相关,并且您应该没问题.

  • 这有几个目的,特别是以尽可能最好的方式防止错误访问和处理资源.我在答案中详细说明了这一点. (2认同)

Cha*_*har 13

BuilderAlertDialog类中的静态内部类.因此,要创建Builder类对象,需要调用AlertDialog.Builder.

由于没有类似AlertDialogBu​​ilder的类,所以你不能这样做.

如果你想要你也可以像下面那样使用.

Builder builder = new Builder(this);
builder.setTitle("foo");
Run Code Online (Sandbox Code Playgroud)

但要像这样使用,你需要将Builder类导入到你的类中

import android.app.AlertDialog.Builder;
Run Code Online (Sandbox Code Playgroud)

而不仅仅是

import android.app.AlertDialog;
Run Code Online (Sandbox Code Playgroud)

一个简单的例子

class A{
     static class B{}
}
Run Code Online (Sandbox Code Playgroud)

你不能用

AB obj = new AB();
Run Code Online (Sandbox Code Playgroud)

你必须使用

A.B obj = new A.B();
Run Code Online (Sandbox Code Playgroud)

希望你现在清楚.