什么是建造者模式?
建造者模式(Builder Pattern)是一种设计模式,用来一步步创建复杂的对象,而不用直接去调用复杂的构造函数或手动设置大量属性。
你可以:
• 按步骤“搭建”对象。
• 自由选择要设置的部分,而不是一次性传一堆参数。
• 更容易阅读代码,维护初始化逻辑。
日常例子类比
想象你在餐厅点套餐:
• 你可以只要主食。
• 也可以点个主食+饮料。
• 或者点主食+饮料+甜点。
这样,你按需搭建自己的“套餐”,而不是总让服务员给你一堆固定的菜。
在编程中,建造者模式的作用就是帮你按需搭建“复杂对象”。
举个例子
需求:创建一个 User 对象,但这个对象有很多属性,有的必须设置,有的可选。
一步步实现建造者模式
第一步:定义产品(最终对象)
这是我们要创建的对象,比如一个用户:
class User {
var name: String
var age: Int
var email: String?
var address: String?
init(name: String, age: Int, email: String? = nil, address: String? = nil) {
self.name = name
self.age = age
self.email = email
self.address = address
}
}
• 必填项:name 和 age。
• 可选项:email 和 address。
第二步:创建建造者类
建造者负责一步步帮你设置 User 对象的属性:
class UserBuilder {
private var name: String = ""
private var age: Int = 0
private var email: String?
private var address: String?
// 设置名字
func setName(_ name: String) -> UserBuilder {
self.name = name
return self
}
// 设置年龄
func setAge(_ age: Int) -> UserBuilder {
self.age = age
return self
}
// 设置邮箱
func setEmail(_ email: String) -> UserBuilder {
self.email = email
return self
}
// 设置地址
func setAddress(_ address: String) -> UserBuilder {
self.address = address
return self
}
// 构建最终的 User 对象
func build() -> User {
return User(name: name, age: age, email: email, address: address)
}
}
第三步:使用建造者创建对象
现在我们用 UserBuilder 来创建 User 对象。看代码:
let user = UserBuilder()
.setName("Alice") // 设置名字
.setAge(25) // 设置年龄
.setEmail("[email protected]") // 设置邮箱(可选)
.setAddress("123 Apple St") // 设置地址(可选)
.build() // 构建最终对象
print("User Info: \(user.name), \(user.age), \(user.email ?? "No Email"), \(user.address ?? "No Address")")
输出:
User Info: Alice, 25, [email protected], 123 Apple St
关键点总结
1. 链式调用:
每个方法都返回 self,所以你可以一行行设置属性,代码更整洁。
2. 灵活设置参数:
不用一次性传很多参数给构造函数,只需要设置需要的。
3. 清晰的结构:
把复杂的初始化逻辑放进 UserBuilder,让代码更易读。
适合场景
1. 对象属性较多且复杂:如有多个可选项或必须项。
2. 需要灵活构造对象:不同场景下需要不同的对象配置。
3. 让代码更清晰易维护:将构造逻辑封装在建造者中。
小练习
试着实现一个 CarBuilder,构建一辆车:
• 必填项:品牌、型号
• 可选项:颜色、发动机类型、价格
用建造者模式实现,然后尝试用它生成一个车辆对象!
demo:
import UIKit
class Car{
var name : String
var model : String
var color : UIColor?
var type : String?
var price : Int?
init(name: String, model: String, color: UIColor? = nil, type: String? = nil, price: Int? = nil) {
self.name = name
self.model = model
self.color = color
self.type = type
self.price = price
}
}
class CarBuilder{
private var name : String = ""
private var model : String = ""
private var color : UIColor?
private var type : String?
private var price : Int?
func setName(_ name : String) -> CarBuilder {
self.name = name
return self
}
func setModel(_ model : String) -> CarBuilder {
self.model = model
return self
}
func setColor(_ color : UIColor) -> CarBuilder{
self.color = color
return self
}
func setType(_ type : String) -> CarBuilder{
self.type = type
return self
}
func setPrice(_ price : Int) -> CarBuilder{
self.price = price
return self
}
func build() -> Car{
return Car(name: name, model: model,color: color,type: type,price: price)
}
}
使用:
let car = CarBuilder()
.setName("Tesla")
.setModel("Model S")
.setColor(.red)
.setType("Electric")
.setPrice(1000000)
.build()
print("Car Info: \(car.name), \(car.model), \(car.color!), \(car.type!), \(car.price!)")