-
-
Save bbvch13531/0687575aaffd4e03693cd2d073e889da to your computer and use it in GitHub Desktop.
import Foundation | |
protocol Orderable { | |
func order(data: [String]) -> [String] | |
} | |
protocol Formattable { | |
func format(parts: Int, data: [String]) -> [String] | |
} | |
// DefaultOrder | |
class DefaultOrder: Orderable { | |
func order(data: [String]) -> [String] { | |
return data | |
} | |
} | |
// DefaultFormat | |
class DefaultFormat: Formattable { | |
func format(parts: Int, data: [String]) -> [String] { | |
let slice = data[parts ..< data.endIndex] | |
return Array(slice) | |
} | |
} | |
// House | |
class House { | |
var data = [String]() | |
let formatter: Formattable | |
internal var attr_reader = [ | |
"the horse and the hound and the horn that belonged to", | |
"the farmer sowing his corn that kept", | |
"the rooster that crowed in", | |
"the morn that woke", | |
"the judge all shaven and shorn that married", | |
"the man all tattered and torn that kissed", | |
"the maiden all forlorn that milked the cow with ", | |
"the crumpled horn that tossed ", | |
"the dog that worried", | |
"the cat that killed ", | |
"the rat that ate", | |
"the malt that lay in", | |
"the house that Jack built" | |
] | |
init(orderer: Orderable?, formatter: Formattable?) { | |
self.formatter = formatter | |
data = orderer.order(data: attr_reader) ?? attr_reader | |
} | |
internal func recite() -> Void { | |
data.enumerated().map { (i, str) in | |
print(line(at: i)) | |
} | |
} | |
internal func parts(at part: Int) -> [String] { | |
return formatter.format(parts: part, data: data) | |
} | |
internal func line(at line: Int) -> String { | |
return "This is \(phrase(at: line).joined()).\n" | |
} | |
internal func phrase(at phrase: Int) -> [String] { | |
return parts(at: phrase) | |
} | |
} | |
class RandomOrder: Orderable { | |
func order(data: [String]) -> [String] { | |
var data = data | |
for i in 0 ..< data.count { | |
let rand = Int.random(in: 0..<data.endIndex) | |
data.swapAt(i, rand) | |
} | |
return data | |
} | |
} | |
class EchoFormat: Formattable { | |
func format(parts: Int, data: [String]) -> [String] { | |
var partArray = [String]() | |
Array(zip(data, data).map{ (first, second) in | |
partArray.append(first + " ") | |
partArray.append(second + " ") | |
}) | |
return partArray | |
} | |
} | |
func testRandHouse(){ | |
let randomOrder = RandomOrder() | |
let randStoryGen = House(orderer: randomOrder) | |
print(randStoryGen.recite()) | |
} | |
func testEchoHouse(){ | |
let echoFormatter = EchoFormat() | |
let echoStoryGen = House(formatter: echoFormatter) | |
// echoStoryGen. | |
print(echoStoryGen.phrase(at: 3)) | |
print("------------------------------------") | |
print(echoStoryGen.line(at: 3)) | |
} | |
func testHouse(){ | |
let storyGen = House() | |
print(storyGen.recite()) | |
} | |
//testEchoHouse() | |
testHouse() | |
//testRandHouse() |
세션의 핵심내용
상속은 구체화할 때만 쓴다.
기능이 확장되는 경우에는 의존성 주입을 써라.
RandomHouse
와 EchoHouse
는 House를 상속받는 개념이 아니다.
=> RandomEchoHouse
를 생각해보면 상속보다 좋은 설계를 할 수 있음을 알 수 있다.
속성에 대한 정의
Random
과 Echo
는 기능, 역할에 대한 속성이다.
House의 기능을 확장시킬 때는 Dependency Injection을 이용해야 한다.
Orderable
,Formatter
프로토콜을 채택하는 클래스를 Dependency로 넣어준다.
결론
DI를 이용해서 Random, Echo, RandomEcho 모두 구현할 수 있게 설계하자.
지금 init은 별로임
init() {}
convenience init(orderer: Orderable) {}
convenience init(formatter: Formattable) {}
convenience init(orderer: Orderable, formatter: Formattable) {}
인자의 갯수가 늘어나면 init이 더 늘어남. 별로임.
init(orderer: Orderable?, formatter: Formattable?) {
self.formatter = formatter ?? DefaultFormat()
data = orderer.order(data: attr_reader) ?? DefaultOrder().order(data: attr_reader)
}
옵셔널로 가져오는 방법 보다 더 좋은 방법은 없을까?
func format(parts: Int, data: [String]) -> [String] {
var partArray = [String]()
Array(zip(data, data).map{ (first, second) in
partArray.append(first + " ")
partArray.append(second + " ")
})
return partArray
}
이 코드도 별로임. reduce 쓰면 되지 않을까
init(orderer: Orderable? = nil, formatter: Formattable? = nil) {
self.formatter = formatter ?? DefaultFormat()
data = orderer?.order(data: attr_reader) ?? DefaultOrder().order(data: attr_reader)
}
Main subject of Session
Inherit is used only for specification
Using dependency injection
When expanding its role.
RandomHouse
and EchoHouse
is not a concept that inherit House
.
=> There’s better architecture when you think about RandomEchoHouse
Definition of attributes.
Random
and Echo
are attributes for it’s role, feature.
Inject class that implement Orderable
, Formatter
protocol as a dependency
Conclusion
Use DI to write better code to implement Random, Echo and RandomEcho
2015 RailsConf Nothing is something.
https://www.youtube.com/watch?v=OMPfEXIlTVE&t=18m55s