热门标签 | 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模式”》 扫码关注微信公众号


推荐阅读
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • macOS Big Sur全新设计大版本更新,10+个值得关注的新功能
    本文介绍了Apple发布的新一代操作系统macOS Big Sur,该系统采用全新的界面设计,包括图标、应用界面、程序坞和菜单栏等方面的变化。新系统还增加了通知中心、桌面小组件、强化的Safari浏览器以及隐私保护等多项功能。文章指出,macOS Big Sur的设计与iPadOS越来越接近,结合了去年iPadOS对鼠标的完善等功能。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 本文介绍了响应式页面的概念和实现方式,包括针对不同终端制作特定页面和制作一个页面适应不同终端的显示。分析了两种实现方式的优缺点,提出了选择方案的建议。同时,对于响应式页面的需求和背景进行了讨论,解释了为什么需要响应式页面。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 抽空写了一个ICON图标的转换程序
    抽空写了一个ICON图标的转换程序,支持png\jpe\bmp格式到ico的转换。具体的程序就在下面,如果看的人多,过两天再把思路写一下。 ... [详细]
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社区 版权所有