热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android源码中的Builder模式及其作用

本文主要解释了什么是Builder模式以及其作用,并结合Android源码来分析Builder模式的实现。Builder模式是将产品的设计、表示和构建进行分离,通过引入建造者角色,简化了构建复杂产品的流程,并且使得产品的构建可以灵活适应变化。使用Builder模式可以解决开发者需要关注产品表示和构建步骤的问题,并且当构建流程发生变化时,无需修改代码即可适配新的构建流程。

《从Android源码来看“Builder模式”》 图片取自zoomy

本文主要解释什么是Builder模式,及其作用。然后结合 Android 源码来看一下Builder模式的实现。

什么是Builder模式

Build 是构建、建造的意思,Builder 模式又称建造者模式。

Builder模式中包括两个核心元素:产品和建造者。这两者可以比作房屋和砖瓦匠。在建造房屋这个过程中,如果建筑公司直接操作房子,除了要对墙壁的颜色、地板的材质、屋顶的形状作出选择外,还要注意建造房屋时的顺序:先打地基、再垒墙壁、最后封顶等等。记住构建房屋的每一步及其顺序,这对建筑公司来说是十分麻烦的。而如果建筑公司引入砖瓦匠的角色,将构建房子的流程等工作交给砖瓦匠,自己只需告诉砖瓦匠:“我要木质地板、白色的墙壁、红色屋顶”即可,构建房屋所涉及的复杂流程就无需关心。另外,当建造房屋的流程发生变化时,建筑公司仍然只需告诉砖瓦匠:“我要木质地板、白色的墙壁、红色屋顶”,而不需作出任何改变。

由上边的比喻可以看出,Builder模式是将房子本身的设计、表示和房子的构建进行分离。不使用此模式,开发者不仅需要关注一个产品的表示,比如AlertDialog的title、button等界面元素,还要关注构建产品的步骤。更加重要的是,如果建造房屋的流程发生变化,不能够再按照以前构建产品的方式创建产品的话,开发者就不得不修改代码来适配新的构建流程。Builder模式可以解决这些问题,为产品增加Builder角色,将构建过程交给Builder实现,开发者只需关心产品属性的设置即可。

就像建筑公司雇佣砖瓦匠需要发工资一样,使用Builder模式的缺点便是需要为增加的Builder对象分配内存。

源码中的Builder模式

在Android源码中,比较常见的是AlertDialog的使用。代码如下:

val builder = AlertDialog.Builder(this)
builder.setMessage("message")
builder.setTitle("title")
...
builder.create().show()

以上代码,无论构建AlertDialog的流程如何变化,都无需改动代码。因为构建过程在builder.create()方法中,而create()方法相对于开发者来说是隐藏的,无需关心的。唯一变化的是create()内部,而这是由Android框架实现的,也就是API发布方进行维护即可。这大大提高了代码的灵活性、可维护性、可扩展性。

AlertDialog的核心代码如下:

public class AlertDialog extends AppCompatDialog implements DialogInterface {
final AlertController mAlert;
protected AlertDialog(@NonNull Context context) {
this(context, 0);
}
@Override
public void setTitle(CharSequence title) {
super.setTitle(title);
mAlert.setTitle(title);
} ...//省略部分类似setTitle()的代码 public static class Builder {
private final AlertController.AlertParams P;
private final int mTheme;
public Builder(@NonNull Context context) {
this(context, resolveDialogTheme(context, 0));
}

public Builder setTitle(@Nullable CharSequence title) {
P.mTitle = title;
return this;
}

...//省略部分类似setTitle()代码

public AlertDialog create() {
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);

...//省略部分代码

return dialog;
}
...//省略部分代码
}
}

Builder 是在 AlertDialog 内部实现的静态类,其主要工作便是通过一系列set方法对 AlertController.AlertParams 对象进行设置,AlertParams类中包含了所有AlertDialog视图属性对应的成员变量,比如mTitle、mMessage等等。然后在create()方法中进行AlertDialog的构建。

Builder模式的实现比较简单,但是除了“AlertDialog初始化十分复杂,参数繁多”这种应用场景之外,还可以在以下场景中使用Builder模式:

  • 构建产品时,不同构建顺序会对产品产生不同的效果
  • 构建产品时,不同构建元素会对产品产生不同的效果
  • 相同方法在以不同执行顺序执行时,产生不同结果
总结

Builder模式用于将产品的构建和展示分离。这样开发者就不必知道产品构建细节,只需对产品的外观进行设计、配置即可。无需担心产品构建流程发生变化。其缺点是需要为Builder对象分配内存。但这也是大多数设计模式的共同缺点。

版权声明
本文首发自简书,搜索作者 QinGeneral
同步发于CSDN博客,搜索作者 QinGeneral
同步发于微信公众号:AndroidRain
无需授权即可转载,甚至无需保留以上版权声明;
转载时请务必注明作者。

《从Android源码来看“Builder模式”》 扫码关注微信公众号


推荐阅读
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
  • 本文介绍了Android开发中Intent的基本概念及其在不同Activity之间的数据传递方式,详细展示了如何通过Intent实现Activity间的跳转和数据传输。 ... [详细]
  • 本文介绍如何使用布局文件在Android应用中排列多行TextView和Button,使其占据屏幕的特定比例,并提供示例代码以帮助理解和实现。 ... [详细]
  • 在 Android 开发中,通过 Intent 启动 Activity 或 Service 时,可以使用 putExtra 方法传递数据。接收方可以通过 getIntent().getExtras() 获取这些数据。本文将介绍如何使用 RoboGuice 框架简化这一过程,特别是 @InjectExtra 注解的使用。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • andr ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 在 Flutter 开发过程中,开发者经常会遇到 Widget 构造函数中的可选参数 Key。对于初学者来说,理解 Key 的作用和使用场景可能是一个挑战。本文将详细探讨 Key 的概念及其应用场景,并通过实例帮助你更好地掌握这一重要工具。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 深入理解Vue.js:从入门到精通
    本文详细介绍了Vue.js的基础知识、安装方法、核心概念及实战案例,帮助开发者全面掌握这一流行的前端框架。 ... [详细]
  • 本文介绍了两种方法,用于检测 Android 设备是否开启了开发者模式。第一种方法通过检查 USB 调试模式的状态,第二种方法则直接判断开发者选项是否启用。这两种方法均提供了代码示例和详细解释。 ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • Redux入门指南
    本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
author-avatar
不能深加工
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有