-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathContents.swift
85 lines (63 loc) · 2.41 KB
/
Contents.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//
// Builder
// ios-design-patterns
//
// Created by Astemir Eleev on 22/08/2018.
// Copyright © 2018 Astemir Eleev. All rights reserved.
//
import Foundation
// Approach #1 (Classic, based on POP)
let cheeseBurgerPlain = Burger(name: "Cheese Burger", patties: 1, bacon: false, cheese: true, pickles: true, mustard: true, tomato: false)
let hamburgerBurgerPlain = Burger(name: "Hamburger", patties: 1, bacon: false, cheese: false, pickles: true, mustard: true, tomato: false)
let cheeseBurger = Burger(builder: CheeseBurgerBuilder())
let hamburgerBurger = Burger(builder: HamburgerBuilder())
let burgerInjectableClosureHam: BurgerInjectable.BurgerInjectasbleClosure = { burger in
burger.name = "Hamburger"
burger.patties = 1
burger.bacon = false
burger.cheese = false
burger.pickles = true
burger.mustard = true
burger.tomato = false
}
let burgerInjectableHam = BurgerInjectable(builder: burgerInjectableClosureHam)
// Approach #2 (Dynamic, Modern, may cause run-time crash, based on POP & Swift's keypaths)
class Song {
private static let UNKNOWN: String = "unknown"
enum Genre {
case rock
case classic
case electro
case rap
case pop
case other(name: String)
}
var name: String = Song.UNKNOWN
var author: String = Song.UNKNOWN
var genre: Genre = .other(name: Song.UNKNOWN)
var duration: Int = -1
var releaseDate: String = Song.UNKNOWN
init() { /* empty implementation */ }
init(name: String, author: String, genre: Genre, duration: Int, releaseDate: String) {
self.name = name
self.author = author
self.genre = genre
self.duration = duration
self.releaseDate = releaseDate
}
}
protocol BuilderProtocol { /* empty, implementation is added to the protocol extension*/ }
extension BuilderProtocol where Self: AnyObject {
@discardableResult
func `init`<T>(_ property: ReferenceWritableKeyPath<Self, T>, with value: T) -> Self {
self[keyPath: property] = value
return self
}
}
extension Song: BuilderProtocol { /* empty implementation */ }
let song = Song()
.`init`(\.author, with: "The Heavy")
.`init`(\.name, with: "Same Ol`")
.`init`(\.genre, with: .rock)
.`init`(\.duration, with: 184)
.`init`(\.releaseDate, with: "2012")