The “builder” pattern is a creational design pattern that is used to construct complex objects step by step. It allows you to create objects with varying configurations without the need to have multiple constructors with different parameter combinations.
Imagine we’re building a pizza ordering app where users can customize their pizzas with various toppings, size, and crust.
struct Pizza {
let size: Size
let crust: Crust
let toppings: [Topping]
}
extension Pizza {
enum Size: String {
case small, medium, large
}
enum Crust: String {
case thin, regular, stuffed
}
struct Topping {
let name: String
}
}
extension Pizza {
class Builder {
private var size: Size?
private var crust: Crust?
private var toppings: [Topping] = []
func setSize(size: Size) -> Builder {
self.size = size
return self
}
func setCrust(crust: Crust) -> Builder {
self.crust = crust
return self
}
func addTopping(_ topping: Topping) -> Builder {
toppings.append(topping)
return self
}
func build() -> Pizza {
guard let size = size, let crust = crust else {
fatalError("Pizza size and crust are required!")
}
return Pizza(size: size, crust: crust, toppings: toppings)
}
}
}
extension Pizza: CustomStringConvertible {
var description: String {
"Pizza: \(size) \(crust) with \(toppings.map { $0.name }.joined(separator: ", "))"
}
}
let pizza = Pizza.Builder()
.setSize(size: .medium)
.setCrust(crust: .thin)
.addTopping(.init(name: "Pepperoni"))
.addTopping(.init(name: "Mushrooms"))
.build()
print(pizza)
// Pizza: medium thin with Pepperoni, Mushrooms
Firstly, we define define the Pizza
struct with its properties: size, crust type, and an array of toppings. We also define enums for Pizza.Size
and Pizza.Crust
and a simple Pizza.Topping
struct.
Secondly, we create a Pizza.Builder
class provides methods for setting the size, crust, and adding toppings to the pizza. Each method returns the builder itself allowing for method chaining for a fluent building experience. The build()
method ensures that size and crust are set and returns the final Pizza
object.
Finally, we use the Pizza.Builder
with method chaining to create a custom pizza with desired size, crust, and toppings.