Skip to content

Instantly share code, notes, and snippets.

@bbvch13531
Last active August 21, 2019 07:01
Show Gist options
  • Save bbvch13531/0687575aaffd4e03693cd2d073e889da to your computer and use it in GitHub Desktop.
Save bbvch13531/0687575aaffd4e03693cd2d073e889da to your computer and use it in GitHub Desktop.
randomEchoHouse
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()
@bbvch13531
Copy link
Author

bbvch13531 commented Jul 21, 2019

2015 RailsConf Nothing is something.

thumbnail
https://www.youtube.com/watch?v=OMPfEXIlTVE&t=18m55s

@bbvch13531
Copy link
Author

세션의 핵심내용

상속은 구체화할 때만 쓴다.
기능이 확장되는 경우에는 의존성 주입을 써라.

RandomHouseEchoHouse 는 House를 상속받는 개념이 아니다.
=> RandomEchoHouse를 생각해보면 상속보다 좋은 설계를 할 수 있음을 알 수 있다.

속성에 대한 정의

RandomEcho 는 기능, 역할에 대한 속성이다.
House의 기능을 확장시킬 때는 Dependency Injection을 이용해야 한다.
Orderable,Formatter 프로토콜을 채택하는 클래스를 Dependency로 넣어준다.

결론

DI를 이용해서 Random, Echo, RandomEcho 모두 구현할 수 있게 설계하자.

@bbvch13531
Copy link
Author

bbvch13531 commented Jul 22, 2019

지금 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)
}

옵셔널로 가져오는 방법 보다 더 좋은 방법은 없을까?

@bbvch13531
Copy link
Author

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 쓰면 되지 않을까

@bbvch13531
Copy link
Author

init(orderer: Orderable? = nil, formatter: Formattable? = nil) {
        self.formatter = formatter ?? DefaultFormat()
        data = orderer?.order(data: attr_reader) ?? DefaultOrder().order(data: attr_reader)
}

@bbvch13531
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment