//Playground friendly
import Foundation
/*
The Builder Pattern helps in the creation of complex objects
*Implemented with Protocols
*/
/* Before Builder Pattern is implemented */
struct ComplexType {
var id: Int
var name: String
var usage: String
var date: NSDate
var line1: String
var line2: String
var line3: String
var value1: Int
var value2: Int
var value3: Double
}
/* Feels clumsy and prone to error */
let exampleObject1 = ComplexType(id: 1, name: "Example Object 1", usage: "No pattern example",
date: NSDate(), line1: "", line2: "",
line3: "", value1: 1, value2: 2, value3: 3.00)
/*
With Builder Pattern
*/
//Implement protocol with all parameters needed for constructor
protocol ComplexTypeBuilder {
var id: Int { get }
var name: String { get }
var usage: String { get }
var date: NSDate { get }
var line1: String { get }
var line2: String { get }
var line3: String { get }
var value1: Int { get }
var value2: Int { get }
var value3: Double { get }
}
//Implement structs that have the logic for setting these values
struct ExampleComplexType1: ComplexTypeBuilder {
let id: Int
let name = "Example Object 1"
let usage = "Showcase Builder pattern"
let date = NSDate()
let line1 = ""
let line2 = ""
let line3 = ""
let value1 = 1
let value2 = 2
let value3 = 3.0
init(id: Int) {
self.id = id
}
}
struct ExampleComplexType2: ComplexTypeBuilder {
let id: Int
let name = "Example Object 2"
let usage = "Reinforce Builder pattern"
let date = NSDate()
let line1 = ""
let line2 = ""
let line3 = ""
let value1 = 3
let value2 = 2
let value3 = 1.0
init(id: Int) {
self.id = id
}
}
//Refactored complex type can now accept one arguement of a ComplexBuilderType type
struct BuilderBasedComplexType {
var id: Int
var name: String
var usage: String
var date: NSDate
var line1: String
var line2: String
var line3: String
var value1: Int
var value2: Int
var value3: Double
init(builder: ComplexTypeBuilder) {
self.id = builder.id
self.name = builder.name
self.usage = builder.usage
self.date = builder.date
self.line1 = builder.line1
self.line2 = builder.line2
self.line3 = builder.line3
self.value1 = builder.value1
self.value2 = builder.value2
self.value3 = builder.value3
}
}
/* Initialization is now more succint */
let builderBasedComplexType = BuilderBasedComplexType(builder: ExampleComplexType1(id: 1))
assert(builderBasedComplexType.id == 1)