技术成神之路:设计模式(二)建造者模式
1.定义
建造者模式(Builder Pattern)是一种创建型设计模式,它允许你分步骤创建复杂对象,而不必直接调用构造函数。建造者模式特别适合那些包含多个组成部分并且构造过程复杂的对象。
2. 结构
建造者模式的主要组成部分包括:
- 产品(Product): 要创建的复杂对象。
- 建造者(Builder): 用于创建产品各个部分的抽象接口。
- 具体建造者(Concrete Builder): 实现Builder接口,构造和装配产品的各个部分。
- 指挥者(Director): 负责管理建造过程,指导建造者如何构建产品。
3. 类图

4. 实现步骤
- 定义产品类: 这类是要创建的复杂对象,包含多个部分。
- 定义抽象建造者接口: 定义构建产品各部分的方法。
- 实现具体建造者类: 实现接口,完成各部分的构建。
- 定义指挥者类: 管理建造过程,使用建造者接口来创建产品。
5. 代码示例
// 产品类
class Computer {private String cpu;private String gpu;private int ram;private int storage;public void setCpu(String cpu) {this.cpu = cpu;}public void setGpu(String gpu) {this.gpu = gpu;}public void setRam(int ram) {this.ram = ram;}public void setStorage(int storage) {this.storage = storage;}
}// 抽象建造者
interface ComputerBuilder {void buildCPU();void buildGPU();void buildRAM();void buildStorage();Computer getResult();
}// 具体建造者
class GamingComputerBuilder implements ComputerBuilder {private Computer computer;public GamingComputerBuilder() {computer = new Computer();}@Overridepublic void buildCPU() {computer.setCpu("Intel i9");}@Overridepublic void buildGPU() {computer.setGpu("NVIDIA RTX 3080");}@Overridepublic void buildRAM() {computer.setRam(32);}@Overridepublic void buildStorage() {computer.setStorage(2000);}@Overridepublic Computer getResult() {return computer;}
}// 指挥者
class Director {private ComputerBuilder builder;public Director(ComputerBuilder builder) {this.builder = builder;}public Computer construct() {builder.buildCPU();builder.buildGPU();builder.buildRAM();builder.buildStorage();return builder.getResult();}
}// 客户端代码示例
public class Client {public static void main(String[] args) {// 创建具体建造者ComputerBuilder builder = new GamingComputerBuilder();// 创建指挥者并传入建造者Director director = new Director(builder);// 构建复杂对象Computer computer = director.construct();}
}
在上述示例中:
Computer是要构建的复杂对象,包含了几个部件(CPU、GPU、RAM、存储)。ComputerBuilder是抽象建造者接口,定义了构建每个部件的方法。GamingComputerBuilder是具体建造者,实现了具体部件的构建方法。Director是指挥者,负责按照一定顺序调用具体建造者的方法来构建对象。Client是客户端代码,通过指挥者来构建复杂对象。
6. 建造者模式的变体
内部类建造者
在实际开发中,使用内部类建造者最为常见,大多数第三方库和安卓系统源码也都使用了建造者模式,主要是方便好用。
public class Car {private final String engine;private final String body;private final String wheels;private final String interior;private Car(Builder builder) {this.engine = builder.engine;this.body = builder.body;this.wheels = builder.wheels;this.interior = builder.interior;}public static class Builder {private String engine;private String body;private String wheels;private String interior;public Builder setEngine(String engine) {this.engine = engine;return this;}public Builder setBody(String body) {this.body = body;return this;}public Builder setWheels(String wheels) {this.wheels = wheels;return this;}public Builder setInterior(String interior) {this.interior = interior;return this;}public Car build() {return new Car(this);}}@Overridepublic String toString() {return "Car [Engine=" + engine + ", Body=" + body + ", Wheels=" + wheels + ", Interior=" + interior + "]";}public static void main(String[] args) {Car car = new Car.Builder().setEngine("V8 Engine").setBody("SUV Body").setWheels("Alloy Wheels").setInterior("Leather Interior").build();System.out.println(car);}
}
7. 建造者模式经典应用 AlertDialog.Builder 源码分析
在 Android 源码中,AlertDialog.Builder 类用于创建 AlertDialog 对象。它提供了一种链式调用的方式来设置对话框的各种属性,如标题、消息、按钮等。
核心成员变量
private final AlertController.AlertParams P;
P 是 AlertController.AlertParams 的一个实例,用于存储和管理对话框的各种参数。
构造函数
public Builder(Context context) {P = new AlertController.AlertParams(new ContextThemeWrapper(context,resolveDialogTheme(context, 0 /* default theme */)));
}
在构造函数中,会创建一个 AlertController.AlertParams 对象,这个对象包含了对话框的参数设置。
设置标题和消息
public Builder setTitle(CharSequence title) {P.mTitle = title;return this;
}public Builder setMessage(CharSequence message) {P.mMessage = message;return this;
}
设置按钮
public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {P.mPositiveButtonText = text;P.mPositiveButtonListener = listener;return this;
}public Builder setNegativeButton(CharSequence text, final OnClickListener listener) {P.mNegativeButtonText = text;P.mNegativeButtonListener = listener;return this;
}
这里的方法它们返回 Builder 对象自身,以支持链式调用。我们在自定义FragmentDialog的时候会经常用到。
创建对话框
public AlertDialog create() {// Context has already been wrapped with the appropriate theme.final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);P.apply(dialog.mAlert);dialog.setCancelable(P.mCancelable);if (P.mCancelable) {dialog.setCanceledOnTouchOutside(true);}dialog.setOnCancelListener(P.mOnCancelListener);dialog.setOnDismissListener(P.mOnDismissListener);if (P.mOnKeyListener != null) {dialog.setOnKeyListener(P.mOnKeyListener);}return dialog;}
create() 方法用于实际创建 AlertDialog 对象。在这里,会通过 AlertController.apply() 方法将 AlertParams 中的参数应用到 AlertDialog 中,并设置对话框的可取消性、监听器等。
使用示例
不是吧啊sir ,AlertDialog谁没用过啊,谁还看你的示例 。
好! 不写了 😊
8. 适用场景及优势
场景:
- 构建和表示分离: 产品的构建过程和最终表示需要解耦。
- 需要构建复杂对象: 产品包含多个部分,构建过程比较复杂。
- 需要多个产品表示: 同样的构建过程可以创建不同的产品表示。
优势:
- 灵活的对象构建: 可以根据需要调整构建过程,创建不同的产品表示。
- 高度可读的代码: 通过分步骤构建对象,使代码更易于理解和维护。
- 良好的扩展性: 可以轻松添加新的构建步骤或修改现有步骤,而不会影响客户端代码。
9. 结论
建造者模式是一种强大的设计模式,特别适合构建过程复杂的对象。它通过将对象的构建过程与表示分离,使得代码更具可读性和可维护性。同时,建造者模式还可以灵活地创建不同的产品表示。
建造者模式不难理解,记住好的代码都是重构出来的,设计模式也是,多写,多练才能真正掌握它的核心。
相关文章:
技术成神之路:设计模式(二)建造者模式
1.定义 建造者模式(Builder Pattern)是一种创建型设计模式,它允许你分步骤创建复杂对象,而不必直接调用构造函数。建造者模式特别适合那些包含多个组成部分并且构造过程复杂的对象。 2. 结构 建造者模式的主要组成部分包括&#…...
基于Springboot+Vue+mysql仓库管理系统仓库进销存管理系统
博主介绍: 大家好,本人精通Java、Python、C#、C、C编程语言,同时也熟练掌握微信小程序、Php和Android等技术,能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验,能够为学生提供各类…...
爬虫scrapy库精简使用大全
一、基本命令 创建项目 scrpay startproject myapp创建爬虫文件 scrapy genspider spider_name "https://www.baidu.com"运行爬虫文件 scrapy crawl spider_name一、使用代理ip 打开中间件middlewares.py,增加以下代码 class ProxyMiddleware:def process…...
Qt - 如何在新线程 (QThread)中使用一个进程 (QProcess)?
在Qt中,QThread 用于处理后台任务,而 QProcess 用于启动和管理外部程序。如果你想在一个新的 QThread 中使用 QProcess,你需要了解 QProcess 并不是专门为在特定线程中运行而设计的。实际上,QProcess 通常在创建它的线程ÿ…...
Qt绘制多线段
最近画辅助线有刚需。 画图准备增加绘制多线段功能。 有哪些方法呢? QPainter Class | Qt GUI 5.15.17 void QPainter::drawPolyline(const QPolygon &points) QPolygon Class | Qt GUI 5.15.17 QPolygon polygon; polygon << QPoint(10, 20) <&…...
去中心化革命:探索区块链技术的前沿
随着信息技术的飞速发展,区块链技术作为一种新兴的去中心化解决方案,正逐渐改变着我们的经济、社会和技术格局。本文将从区块链的基本原理、当前的应用实例以及未来的发展趋势三个方面,深入探讨区块链技术在革命性变革中的角色和影响。 1. 区…...
2024年湖南省各市科小申报时间(科技型中小企业申报流程、条件、好处)新政
湖南省各市科小申报时间流程 一、评价管理 省科技厅牵头负责科技型中小企业评价工作的组织和监督、实地核查、公示公告、入库登记及编号撤销和集中抽查工作,及时处理相关异议、投诉和举报信息。 各市州科技局负责科技型中小企业评价工作的具体实施,组…...
【JD-GUI】MacOS 中使用Java反编译工具JD-GUI
希望文章能给到你启发和灵感~ 如果觉得文章对你有帮助的话,点赞 关注 收藏 支持一下博主吧~ 阅读指南 开篇说明概念理解一、基础环境说明1.1 硬件环境1.2 软件环境 二、下载与安装2.1 选择对应版本2.2 解压运行排除异常:2.3 关于…...
C++:求梯形面积
梯形面积 已知上底15厘米,下底25厘米,问梯形面积值是多少? #include<iostream> using namespace std; int main() {//梯形的面积公式(上底下底) 高 2//上底变量、下底变量int s,d,h,m;s15;d25;h 2*150 * 2/s ;…...
学会python——在excel中写入数据(python实例十三)
目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3 .想Excel中写入数据 3.1 代码构思 3.2 代码实例 3.3 运行结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的…...
Stable Diffusion【基础篇】:降噪强度(denoising strength)
提到降噪强度(denoising strength),大家一定不会陌生,这个参数是图生图中最关键的参数之一。今天在Stable Diffusion Art网站看到一篇介绍降噪强度(denoising strength)的文章(地址:…...
【Python】语法入门
文章目录 Python 基础语法:打印和变量打印和变量的基本语法打印变量 变量操作变量的命名规则打印和变量的应用场景示例:基本计算器 Python 基础语法:列表推导式列表推导式的基本语法基本示例带条件的列表推导式列表推导式的应用场景 Python 基…...
匠心独运:红酒与手工艺的很好结合
在岁月的长河中,红酒与手工艺都以其不同的魅力和技艺,书写着各自的故事。当这两者相遇,仿佛是一场跨越时空的对话,不仅展现了匠心独运的技艺之美,更在无声中诉说着对品质与生活的热爱。今天,就让我们一起探…...
第20章 Mac+VSCode配置C++环境
1. 下载VSCode VSCode下载地址在mac终端里输入xcode- select --install命令,根据提示安装xcode工具。 2. 安装插件(4个) 打开VScode,点击应用右侧菜单栏 C/C(必装) Code Runner(必装…...
FactoryBean 原理简介
FactoryBean 首先是一个工厂类,它可以生产指定的Bean,特殊之处在于它可以向Spring容器中注册两个Bean,一个是它本身,一个是FactoryBean.getObject()方法返回值所代表的Bean。通过实现 FactoryBean 接口,你可以控制某个…...
Redis中hash类型的操作命令(命令的语法、返回值、时间复杂度、注意事项、操作演示)
文章目录 字符串和哈希类型相比hset 命令hget 命令hexistshdelhkeyshvalshgetallhmgethlenhsetnxhincrbyhincrbyfloat 字符串和哈希类型相比 假设有以下一种场景:现在要在 Redis 中存储一个用户的基本信息(id1、namezhangsan、age17),下图表示使用字符串…...
UE5基本操作(二)
文章目录 前言相机的移动速度修改默认地图使用初学者内容包文件夹结构 总结 前言 在我们的上一篇文章中,我们已经介绍了一些Unreal Engine 5(UE5)的基本操作。UE5是一款强大的游戏开发引擎,它提供了许多工具和功能,使…...
React Navigation 和 Expo Router
React Navigation 是 React Native 社区最常用的导航库,其具有高度可定制性且性能良好的特性。它提供了一系列导航器(如堆栈导航器、标签导航器、抽屉导航器等),可以满足绝大多数的页面导航需求。 Expo Router 是 Expo 官方最新发…...
如何使用python网络爬虫批量获取公共资源数据教程?
原文链接:如何使用python网络爬虫批量获取公共资源数据教程?https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247608240&idx4&snef281f66727afabfaae2066c6e92f792&chksmfa826657cdf5ef41571115328a09b9d34367d8b11415d5a5781dc4c…...
常见位运算总结
1.基础位运算 左移 (<<): 最左侧位不要了, 最右侧补 0 右移(>>): 最右侧位不要了, 最左侧补符号位(正数补0, 负数补1) 按位取反(~):如果该位为 0 则转为 1, 如果该位为 1 则转为…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...
LangChain【6】之输出解析器:结构化LLM响应的关键工具
文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器?1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...
【技巧】dify前端源代码修改第一弹-增加tab页
回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码,在知识库增加一个tab页"HELLO WORLD",完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...
