Slide 1

Slide 1 text

DI with Reader Monad iOS Test Night #7 2018/03/26 @to4iki 1

Slide 2

Slide 2 text

Me • Takezawa Toshiki • @to4iki • iOS Engineer • ! ☕ ♨ 2

Slide 3

Slide 3 text

what DI? 3

Slide 4

Slide 4 text

֎෦͔Βґଘ(ΦϒδΣΫτ) Λ஫ೖͰ͖ΔΑ͏ʹ͢Δ σβΠϯύλʔϯ 4

Slide 5

Slide 5 text

! ϝϦοτ • ίϯϙʔωϯτಉ͕࢜ૄ݁߹ʹͳΔ • I/FΛࢀর͢Δ͜ͱʹͳΔ • ΦϒδΣΫτͷੜ੒ͱ࢖༻͕෼཭͞ΕΔ • ಈ࡞ΛॊೈʹΧελϚΠζͰ͖Δ • ґଘ͢ΔΦϒδΣΫτΛࠩ͠ସ͑Δ͜ͱ͕Ͱ͖Δ • -> ςετ͕ॻ͚Δ ! 5

Slide 6

Slide 6 text

ಈతDI • DI Container ੩తDI • Initializer(Constructor) Injection • Property(Setter) Injection • Cake Pattern • Reader Monad 6

Slide 7

Slide 7 text

Reader Monad 7

Slide 8

Slide 8 text

ؔ਺Ϟφυ (Input) -> Element ͷϥούʔ struct Reader { typealias WorkFactory = (Input) -> Element private let workFactory: WorkFactory func execute(_ input: Input) -> Element { return workFactory(input) } } 8

Slide 9

Slide 9 text

map / flatMap func map(_ f: @escaping (Element) -> T) -> Reader { return Reader { input in f(self.execute(input)) } } func flatMap(_ f: @escaping (Element) -> Reader) -> Reader { return Reader { input in f(self.execute(input)).execute(input) } } 9

Slide 10

Slide 10 text

ఆٛ͸͜Μ͚ͩ 10

Slide 11

Slide 11 text

ex. let plusTwoReader = Reader { $0 + 2 } let xxxReader = plusTwoReader .map { $0 * 2 } .map { "value is \($0)" } xxxReader.execute(1) // "value is 6" xxxReader.execute(2) // "value is 8" plusTwoReader .flatMap { x in Reader { y in x * y } } .execute(3) // 18 11

Slide 12

Slide 12 text

ධՁ͢Δ·Ͱɺ Πϯϓοτ(ґଘ)Λ ஗Ԇͤ͞Δ͜ͱ͕Ͱ͖Δ 12

Slide 13

Slide 13 text

Example DI 13

Slide 14

Slide 14 text

ex. ! protocol UserServiceType { func find(by id: User.Id) -> User? } struct UserService: UserServiceType { func find(by id: User.Id) -> User? { ... } } 14

Slide 15

Slide 15 text

ex. ! Dependency protocol Module { var userService: UserServiceType { get } var tweetService: TweetServiceType { get } } 15

Slide 16

Slide 16 text

ex. ! Client func getTweets(by userId: User.Id) -> Reader { return Reader { module in module.userService.find(by: userId) .map { $0.name } .map { module.tweetService.findAll(by: $0) } ?? [] } } 16

Slide 17

Slide 17 text

ex. ! Injection struct ProductionModule: Module { var userService: UserServiceType { return UserService.shared } var tweetService: TweetServiceType { return TweetService.shared } } getTweets("prod").execute(ProductionModule()) // [ATweet, BTweet, ...] getTweets("test").execute(MockModule()) // [TestTweet] 17

Slide 18

Slide 18 text

DI with Reader Monad Pros • ΦϒδΣΫτ୯ҐͰ͸ͳ͘ɺؔ਺୯Ґͷࡉ͔ͳDI͕ग़དྷΔ Cons • ReaderܕʹϩοΫΠϯ͞ΕΔ • ೉͍͠ • ґଘ͕ෳ਺ʹͳΔͱѻ͍ʹ͍͘ • Ϟφυ͕ωετͨ࣌͠ͷѻ͍͕৑௕ʹͳΔ 18

Slide 19

Slide 19 text

Conclusion • DIख๏ͷҰͭʹReader MonadΛ࢖༻ͨ͠ํ๏ ͕͋Δ • SwiftͰѻ͏ʹ͸࣮༻͸ݫ͍͠ҹ৅ • functional-programmingΛಥ͖ਐΊΔڧ ͍ҙࢤͱ֮ޛ͕͋Ε͹... • ༷ʑͳDIख๏͕͋Δ͕ɺίϯςΩετ (ϝϯόɾจԽ)ʹԠͨ͡΋ͷΛબ୒͠·͠ΐ͏ʂ 19

Slide 20

Slide 20 text

https://github.com/ to4iki/Reader 20

Slide 21

Slide 21 text

Thanks 21