|
| 1 | +//: [Behavioral](Behavioral) | |
| 2 | +//: Creational | |
| 3 | +//: [Structural](Structural) |
| 4 | +/*: |
| 5 | +Creational |
| 6 | +========== |
| 7 | + |
| 8 | +> In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation. |
| 9 | +> |
| 10 | +>**Source:** [wikipedia.org](http://en.wikipedia.org/wiki/Creational_pattern) |
| 11 | +*/ |
| 12 | +import Swift |
| 13 | +import Foundation/*: |
| 14 | +🌰 Abstract Factory |
| 15 | +------------------- |
| 16 | + |
| 17 | +The abstract factory pattern is used to provide a client with a set of related or dependant objects. |
| 18 | +The "family" of objects created by the factory are determined at run-time. |
| 19 | + |
| 20 | +### Example |
| 21 | +*/ |
| 22 | +/*: |
| 23 | +Protocols |
| 24 | +*/ |
| 25 | +protocol Decimal { |
| 26 | + func stringValue() -> String |
| 27 | +} |
| 28 | + |
| 29 | +protocol NumberFactoryProtocol { |
| 30 | + func numberFromString(string : String) -> Decimal |
| 31 | +} |
| 32 | + |
| 33 | +// Number implementations |
| 34 | + |
| 35 | +struct NextStepNumber : Decimal { |
| 36 | + private var nextStepNumber : NSNumber |
| 37 | + |
| 38 | + func stringValue() -> String { return nextStepNumber.stringValue } |
| 39 | +} |
| 40 | + |
| 41 | +struct SwiftNumber : Decimal { |
| 42 | + private var swiftInt : Int |
| 43 | + |
| 44 | + func stringValue() -> String { return "\(swiftInt)" } |
| 45 | +} |
| 46 | +/*: |
| 47 | +Factories |
| 48 | +*/ |
| 49 | +class NextStepNumberFactory : NumberFactoryProtocol { |
| 50 | + func numberFromString(string : String) -> Decimal { |
| 51 | + return NextStepNumber(nextStepNumber:NSNumber(longLong:(string as NSString).longLongValue)) |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +class SwiftNumberFactory : NumberFactoryProtocol { |
| 56 | + func numberFromString(string : String) -> Decimal { |
| 57 | + return SwiftNumber(swiftInt:(string as NSString).integerValue) |
| 58 | + } |
| 59 | +} |
| 60 | +/*: |
| 61 | +Abstract factory |
| 62 | +*/ |
| 63 | +enum NumberType { |
| 64 | + case NextStep, Swift |
| 65 | +} |
| 66 | + |
| 67 | +class NumberAbstractFactory { |
| 68 | + class func numberFactoryType(type : NumberType) -> NumberFactoryProtocol { |
| 69 | + |
| 70 | + switch type { |
| 71 | + case .NextStep: |
| 72 | + return NextStepNumberFactory() |
| 73 | + case .Swift: |
| 74 | + return SwiftNumberFactory() |
| 75 | + } |
| 76 | + } |
| 77 | +} |
| 78 | +/*: |
| 79 | +### Usage |
| 80 | +*/ |
| 81 | +let factoryOne = NumberAbstractFactory.numberFactoryType(.NextStep) |
| 82 | +let numberOne = factoryOne.numberFromString("1") |
| 83 | +numberOne.stringValue() |
| 84 | + |
| 85 | +let factoryTwo = NumberAbstractFactory.numberFactoryType(.Swift) |
| 86 | +let numberTwo = factoryTwo.numberFromString("2") |
| 87 | +numberTwo.stringValue() |
| 88 | +/*: |
| 89 | +👷 Builder |
| 90 | +---------- |
| 91 | + |
| 92 | +The builder pattern is used to create complex objects with constituent parts that must be created in the same order or using a specific algorithm. |
| 93 | +An external class controls the construction algorithm. |
| 94 | + |
| 95 | +### Example |
| 96 | +*/ |
| 97 | +class DeathStarBuilder { |
| 98 | + |
| 99 | + var x: Double? |
| 100 | + var y: Double? |
| 101 | + var z: Double? |
| 102 | + |
| 103 | + typealias BuilderClosure = (DeathStarBuilder) -> () |
| 104 | + |
| 105 | + init(buildClosure: BuilderClosure) { |
| 106 | + buildClosure(self) |
| 107 | + } |
| 108 | +} |
| 109 | + |
| 110 | +struct DeathStar : CustomStringConvertible { |
| 111 | + |
| 112 | + let x: Double |
| 113 | + let y: Double |
| 114 | + let z: Double |
| 115 | + |
| 116 | + init?(builder: DeathStarBuilder) { |
| 117 | + |
| 118 | + if let x = builder.x, y = builder.y, z = builder.z { |
| 119 | + self.x = x |
| 120 | + self.y = y |
| 121 | + self.z = z |
| 122 | + } else { |
| 123 | + return nil |
| 124 | + } |
| 125 | + } |
| 126 | + |
| 127 | + var description:String { |
| 128 | + return "Death Star at (x:\(x) y:\(y) z:\(z))" |
| 129 | + } |
| 130 | +} |
| 131 | +/*: |
| 132 | +### Usage |
| 133 | +*/ |
| 134 | +let empire = DeathStarBuilder { builder in |
| 135 | + builder.x = 0.1 |
| 136 | + builder.y = 0.2 |
| 137 | + builder.z = 0.3 |
| 138 | +} |
| 139 | + |
| 140 | +let deathStar = DeathStar(builder:empire) |
| 141 | +/*: |
| 142 | +🏭 Factory Method |
| 143 | +----------------- |
| 144 | + |
| 145 | +The factory pattern is used to replace class constructors, abstracting the process of object generation so that the type of the object instantiated can be determined at run-time. |
| 146 | + |
| 147 | +### Example |
| 148 | +*/ |
| 149 | +protocol Currency { |
| 150 | + func symbol() -> String |
| 151 | + func code() -> String |
| 152 | +} |
| 153 | + |
| 154 | +class Euro : Currency { |
| 155 | + func symbol() -> String { |
| 156 | + return "€" |
| 157 | + } |
| 158 | + |
| 159 | + func code() -> String { |
| 160 | + return "EUR" |
| 161 | + } |
| 162 | +} |
| 163 | + |
| 164 | +class UnitedStatesDolar : Currency { |
| 165 | + func symbol() -> String { |
| 166 | + return "$" |
| 167 | + } |
| 168 | + |
| 169 | + func code() -> String { |
| 170 | + return "USD" |
| 171 | + } |
| 172 | +} |
| 173 | + |
| 174 | +enum Country { |
| 175 | + case UnitedStates, Spain, UK, Greece |
| 176 | +} |
| 177 | + |
| 178 | +class CurrencyFactory { |
| 179 | + class func currencyForCountry(country:Country) -> Currency? { |
| 180 | + |
| 181 | + switch country { |
| 182 | + case .Spain, .Greece : |
| 183 | + return Euro() |
| 184 | + case .UnitedStates : |
| 185 | + return UnitedStatesDolar() |
| 186 | + default: |
| 187 | + return nil |
| 188 | + } |
| 189 | + |
| 190 | + } |
| 191 | +} |
| 192 | +/*: |
| 193 | +### Usage |
| 194 | +*/ |
| 195 | +let noCurrencyCode = "No Currency Code Available" |
| 196 | + |
| 197 | +CurrencyFactory.currencyForCountry(.Greece)?.code() ?? noCurrencyCode |
| 198 | +CurrencyFactory.currencyForCountry(.Spain)?.code() ?? noCurrencyCode |
| 199 | +CurrencyFactory.currencyForCountry(.UnitedStates)?.code() ?? noCurrencyCode |
| 200 | +CurrencyFactory.currencyForCountry(.UK)?.code() ?? noCurrencyCode |
| 201 | +/*: |
| 202 | +🃏 Prototype |
| 203 | +------------ |
| 204 | + |
| 205 | +The prototype pattern is used to instantiate a new object by copying all of the properties of an existing object, creating an independent clone. |
| 206 | +This practise is particularly useful when the construction of a new object is inefficient. |
| 207 | + |
| 208 | +### Example |
| 209 | +*/ |
| 210 | +class ChungasRevengeDisplay { |
| 211 | + var name: String? |
| 212 | + let font: String |
| 213 | + |
| 214 | + init(font: String) { |
| 215 | + self.font = font |
| 216 | + } |
| 217 | + |
| 218 | + func clone() -> ChungasRevengeDisplay { |
| 219 | + return ChungasRevengeDisplay(font:self.font) |
| 220 | + } |
| 221 | +} |
| 222 | +/*: |
| 223 | +### Usage |
| 224 | +*/ |
| 225 | +let Prototype = ChungasRevengeDisplay(font:"GotanProject") |
| 226 | + |
| 227 | +let Philippe = Prototype.clone() |
| 228 | +Philippe.name = "Philippe" |
| 229 | + |
| 230 | +let Christoph = Prototype.clone() |
| 231 | +Christoph.name = "Christoph" |
| 232 | + |
| 233 | +let Eduardo = Prototype.clone() |
| 234 | +Eduardo.name = "Eduardo" |
| 235 | +/*: |
| 236 | +💍 Singleton |
| 237 | +------------ |
| 238 | + |
| 239 | +The singleton pattern ensures that only one object of a particular class is ever created. |
| 240 | +All further references to objects of the singleton class refer to the same underlying instance. |
| 241 | +There are very few applications, do not overuse this pattern! |
| 242 | + |
| 243 | +### Example: |
| 244 | +*/ |
| 245 | +class DeathStarSuperlaser { |
| 246 | + static let sharedInstance = DeathStarSuperlaser() |
| 247 | + |
| 248 | + private init() { |
| 249 | + // Private initialization to ensure just one instance is created. |
| 250 | + } |
| 251 | +} |
| 252 | +/*: |
| 253 | +### Usage: |
| 254 | +*/ |
| 255 | +let laser = DeathStarSuperlaser.sharedInstance |
0 commit comments