Builder is a creational design pattern that lets you construct complex objects step by step. The pattern allows you to produce different types and representations of an object using the same construction code.
class Phone {
var osVersion = 0
var model = ""
var cpuCodeName = ""
var ramSize = 0
}
Builder
class PhoneBuilder {
let phone = Phone()
func getPhone() -> Phone {
return self.phone
}
}
Concrete Builder
class iPhoneXBuilder: PhoneBuilder {
func setOSVersion() {
self.phone.osVersion = 11
}
func setModel() {
self.phone.model = "iPhone X"
}
func setCPUCodeName() {
self.phone.cpuCodeName = "A11"
}
func setRamSize() {
self.phone.ramSize = 3072
}
}
class AndroidPhoneBuilder: PhoneBuilder{
func setOSVersion() {
self.phone.osVersion = 5
}
func setModel() {
self.phone.model = "Android Phone"
}
func setCPUCodeName() {
self.phone.cpuCodeName = "Mediatec"
}
func setRamSize() {
self.phone.ramSize = 1024
}
}
Director
class Director {
var builder = PhoneBuilder()
func setBuilder(builder: PhoneBuilder) {
self.builder = builder
}
func getPhone() -> Phone {
return self.builder.getPhone()
}
func constructPhone() {
if let builder = builder as? iPhoneXBuilder {
builder.setOSVersion()
builder.setModel()
builder.setCPUCodeName()
builder.setRamSize()
} else if let builder = builder as? AndroidPhoneBuilder {
builder.setOSVersion()
builder.setModel()
builder.setCPUCodeName()
builder.setRamSize()
}
}
}
Usage:
let iPhone = iPhoneXBuilder()
let androidPhone = AndroidPhoneBuilder()
let director = Director()
director.setBuilder(builder: iPhone)
director.constructPhone()
let phone1 = director.getPhone()
print("Model: \(phone1.model) ram: \(phone1.ramSize)")
director.setBuilder(builder: androidPhone)
director.constructPhone()
let phone2 = director.getPhone()
print("Model: \(phone2.model) ram: \(phone2.ramSize)")
Pros and Cons