在软件设计中,我们常常面临复杂对象的创建问题。当构造函数参数过多、配置灵活多变时,传统的构造方法会变得臃肿不堪。构建者模式正是解决这一痛点的优雅方案。
🎯 模式意图
构建者模式是一种创建型设计模式,它将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。
核心思想:不要用一个大而全的构造函数来创建复杂对象,而是通过一步步的链式调用来逐步构建。
🔍 现实世界比喻
想象一下你去定制一台高性能电脑:
-
你不需要记住所有配置参数的具体顺序
-
你可以一步步选择:CPU → 内存 → 硬盘 → 显卡...
-
销售员(构建者)会确保配置的合理性
-
最终你得到一台完美符合需求的电脑
这就是构建者模式的精髓!
💻 传统构造方法的问题
先来看看我们想要避免的"反模式":
// ❌ 糟糕的构造方法:参数过多,难以阅读和维护
class Computer(
val cpu: String,
val memory: String,
val storage: String,
val graphicsCard: String,
val motherboard: String,
val powerSupply: String,
val coolingSystem: String,
val isRGB: Boolean = false
)
// 使用时的噩梦:
val computer = Computer(
"Intel i9",
"32GB DDR5",
"1TB NVMe SSD",
"RTX 4080",
"Z790",
"850W",
"Liquid Cooling",
true
)
问题分析:
-
参数顺序容易出错
-
可读性极差,不知道每个参数的含义
-
难以处理可选参数
-
构造过程僵化,缺乏灵活性
🚀 构建者模式的优雅实现
基础构建者模式
class Computer private constructor(
val cpu: String,
val memory: String,
val storage: String,
val graphicsCard: String?,
val motherboard: String,
val powerSupply: String,
val coolingSystem: String?,
val isRGB: Boolean
) {
// 构建者类
class Builder {
// 必需参数
private var cpu: String = ""
private var memory: String = ""
private var storage: String = ""
private var motherboard: String = ""
private var powerSupply: String = ""
// 可选参数(有默认值)
private var graphicsCard: String? = null
private var coolingSystem: String? = null
private var isRGB: Boolean = false
fun setCpu(cpu: String) = apply { this.cpu = cpu }
fun setMemory(memory: String) = apply { this.memory = memory }
fun setStorage(storage: String) = apply { this.storage = storage }
fun setMotherboard(motherboard: String) = apply { this.motherboard = motherboard }
fun setPowerSupply(powerSupply: String) = apply { this.powerSupply = powerSupply }
fun setGraphicsCard(graphicsCard: String?) = apply { this.graphicsCard = graphicsCard }
fun setCoolingSystem(coolingSystem: String?) = apply { this.coolingSystem = coolingSystem }
fun setIsRGB(isRGB: Boolean) = apply { this.isRGB = isRGB }
fun build(): Computer {
// 参数校验
require(cpu.isNotBlank()) { "CPU不能为空" }
require(memory.isNotBlank()) { "内存不能为空" }
require(storage.isNotBlank()) { "存储不能为空" }
return Computer(cpu, memory, storage, graphicsCard,
motherboard, powerSupply, coolingSystem, isRGB)
}
}
}
流畅的链式调用
// ✅ 优雅的使用方式
val gamingComputer = Computer.Builder()
.setCpu("Intel i9-13900K")
.setMemory("32GB DDR5")
.setStorage("2TB NVMe SSD")
.setMotherboard("Z790")
.setPowerSupply("1000W")
.setGraphicsCard("RTX 4090")
.setCoolingSystem("360mm Liquid Cooling")
.setIsRGB(true)
.build()
val officeComputer = Computer.Builder()
.setCpu("Intel i5-13400")
.setMemory("16GB DDR4")
.setStorage("512GB SSD")
.setMotherboard("B760")
.setPowerSupply("550W")
// 可选参数可以不设置,使用默认值
.build()
🌟 Kotlin 的 DSL 风格构建者
Kotlin 的语言特性让构建者模式更加优雅:
// 使用 Kotlin 的 DSL 特性
class Computer private constructor(builder: Builder) {
val cpu: String = builder.cpu
val memory: String = builder.memory
val storage: String = builder.storage
val graphicsCard: String? = builder.graphicsCard
val isRGB: Boolean = builder.isRGB
class Builder {
var cpu: String = ""
var memory: String = ""
var storage: String = ""
var graphicsCard: String? = null
var isRGB: Boolean = false
fun build() = Computer(this)
}
}
// DSL 构建函数
fun computer(block: Computer.Builder.() -> Unit): Computer {
return Computer.Builder().apply(block).build()
}
// 使用 DSL 风格构建
val myComputer = computer {
cpu = "Intel i7-13700K"
memory = "64GB DDR5"
storage = "1TB SSD + 2TB HDD"
graphicsCard = "RTX 4070"
isRGB = true
}
🏗️ 导演者模式:构建过程的复用
对于常见的构建场景,可以引入导演者来封装构建逻辑:
class ComputerDirector {
fun buildGamingComputer(): Computer {
return Computer.Builder()
.setCpu("Intel i9-13900K")
.setMemory("32GB DDR5")
.setStorage("2TB NVMe SSD")
.setGraphicsCard("RTX 4090")
.setIsRGB(true)
.build()
}
fun buildOfficeComputer(): Computer {
return Computer.Builder()
.setCpu("Intel i5-13400")
.setMemory("16GB DDR4")
.setStorage("512GB SSD")
.build()
}
}
// 使用导演者
val director = ComputerDirector()
val gamingPC = director.buildGamingComputer()
val officePC = director.buildOfficeComputer()
📊 模式结构解析
Client → Builder → ConcreteBuilder → Product
↑
Director(可选)
-
Builder:构建者接口,定义构建步骤
-
ConcreteBuilder:具体构建者,实现构建细节
-
Product:被构建的复杂对象
-
Director:导演者,封装常见构建流程(可选)
-
Client:客户端,使用构建者创建对象
🎯 优势总结
|
优势 |
说明 |
|---|---|
|
封装性好 |
隐藏产品的内部结构和构建过程 |
|
扩展性强 |
增加新的具体构建者很容易,符合开闭原则 |
|
精细控制 |
可以精细控制构建过程,逐步构建复杂对象 |
|
代码可读性 |
链式调用让代码更加清晰易懂 |
|
参数校验 |
可以在 build() 方法中进行集中参数校验 |
🔄 与其他模式的关系
-
与工厂模式:工厂模式关注产品整体的创建,构建者模式关注产品的逐步组装
-
与组合模式:构建者模式常用来构建组合模式中的复杂树形结构
-
与模板方法模式:导演者类可以使用模板方法定义构建流程
💡 实际应用场景
Android 开发中的 AlertDialog
AlertDialog.Builder(this)
.setTitle("提示")
.setMessage("确定要删除吗?")
.setPositiveButton("确定") { dialog, which -> }
.setNegativeButton("取消") { dialog, which -> }
.create()
.show()
Retrofit 的网络请求构建
interface ApiService {
@GET("users/{id}")
fun getUser(@Path("id") userId: String): Call<User>
}
Glide 的图片加载配置
Glide.with(context)
.load(imageUrl)
.placeholder(R.drawable.placeholder)
.error(R.drawable.error)
.into(imageView)
🚀 最佳实践建议
-
当构造参数超过4个时,考虑使用构建者模式
-
使用链式调用(返回this)来提升流畅度
-
在build()方法中进行参数校验,确保对象有效性
-
考虑不可变对象,将构建完成的对象设为不可变
-
对于常见配置,使用导演者模式提供预设方案
总结
构建者模式通过分步构建和链式调用,完美解决了复杂对象的创建问题。它让代码更加:
-
✅ 可读:清晰的构建步骤
-
✅ 灵活:支持多种配置组合
-
✅ 安全:参数校验和不可变对象
-
✅ 可维护:构建逻辑集中管理
下次当你面对一个"庞大"的构造函数时,不妨考虑使用构建者模式,让对象创建变得优雅而愉快!
954

被折叠的 条评论
为什么被折叠?



