Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
DI with "Reader Monad"
Search
to4iki
March 26, 2018
1
1.3k
DI with "Reader Monad"
iOS Test Night #7
2018/03/26
https://github.com/to4iki/Reader
to4iki
March 26, 2018
Tweet
Share
More Decks by to4iki
See All by to4iki
Claude Code の活用事例
to4iki
0
62
Swift Concurrencyを利用したUIViewController表示の排他制御の実装
to4iki
0
3.3k
ケースに応じたUICollectionViewのレイアウト実装パターン
to4iki
1
4.7k
ビューインプレッションの計測方法
to4iki
1
1.1k
秘伝の `gitconfig`
to4iki
1
440
Abema iOS Architecture
to4iki
12
3.4k
timetable-bot
to4iki
0
14k
BLoC Pattern Introduction with Swift
to4iki
2
1.3k
nel
to4iki
0
160
Featured
See All Featured
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
20k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
228
22k
How to Ace a Technical Interview
jacobian
276
23k
GitHub's CSS Performance
jonrohan
1031
460k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.3k
Code Review Best Practice
trishagee
68
18k
It's Worth the Effort
3n
184
28k
Documentation Writing (for coders)
carmenintech
71
4.9k
Side Projects
sachag
455
42k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Transcript
DI with Reader Monad iOS Test Night #7 2018/03/26 @to4iki
1
Me • Takezawa Toshiki • @to4iki • iOS Engineer •
! ☕ ♨ 2
what DI? 3
֎෦͔Βґଘ(ΦϒδΣΫτ) ΛೖͰ͖ΔΑ͏ʹ͢Δ σβΠϯύλʔϯ 4
! ϝϦοτ • ίϯϙʔωϯτಉ͕࢜ૄ݁߹ʹͳΔ • I/FΛࢀর͢Δ͜ͱʹͳΔ • ΦϒδΣΫτͷੜͱ༻͕͞ΕΔ • ಈ࡞ΛॊೈʹΧελϚΠζͰ͖Δ
• ґଘ͢ΔΦϒδΣΫτΛࠩ͠ସ͑Δ͜ͱ͕Ͱ͖Δ • -> ςετ͕ॻ͚Δ ! 5
ಈతDI • DI Container ੩తDI • Initializer(Constructor) Injection • Property(Setter)
Injection • Cake Pattern • Reader Monad 6
Reader Monad 7
ؔϞφυ (Input) -> Element ͷϥούʔ struct Reader<Input, Element> { typealias
WorkFactory = (Input) -> Element private let workFactory: WorkFactory func execute(_ input: Input) -> Element { return workFactory(input) } } 8
map / flatMap func map<T>(_ f: @escaping (Element) -> T)
-> Reader<Input, T> { return Reader<Input, T> { input in f(self.execute(input)) } } func flatMap<T>(_ f: @escaping (Element) -> Reader<Input, T>) -> Reader<Input, T> { return Reader<Input, T> { input in f(self.execute(input)).execute(input) } } 9
ఆٛ͜Μ͚ͩ 10
ex. let plusTwoReader = Reader<Int, Int> { $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<Int, Int> { y in x * y } } .execute(3) // 18 11
ධՁ͢Δ·Ͱɺ Πϯϓοτ(ґଘ)Λ Ԇͤ͞Δ͜ͱ͕Ͱ͖Δ 12
Example DI 13
ex. ! protocol UserServiceType { func find(by id: User.Id) ->
User? } struct UserService: UserServiceType { func find(by id: User.Id) -> User? { ... } } 14
ex. ! Dependency protocol Module { var userService: UserServiceType {
get } var tweetService: TweetServiceType { get } } 15
ex. ! Client func getTweets(by userId: User.Id) -> Reader<Module, [Tweet]>
{ return Reader { module in module.userService.find(by: userId) .map { $0.name } .map { module.tweetService.findAll(by: $0) } ?? [] } } 16
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
DI with Reader Monad Pros • ΦϒδΣΫτ୯ҐͰͳ͘ɺؔ୯Ґͷࡉ͔ͳDI͕ग़དྷΔ Cons • ReaderܕʹϩοΫΠϯ͞ΕΔ
• ͍͠ • ґଘ͕ෳʹͳΔͱѻ͍ʹ͍͘ • Ϟφυ͕ωετͨ࣌͠ͷѻ͍͕ʹͳΔ 18
Conclusion • DIख๏ͷҰͭʹReader MonadΛ༻ͨ͠ํ๏ ͕͋Δ • SwiftͰѻ͏ʹ࣮༻ݫ͍͠ҹ • functional-programmingΛಥ͖ਐΊΔڧ ͍ҙࢤͱ֮ޛ͕͋Ε...
• ༷ʑͳDIख๏͕͋Δ͕ɺίϯςΩετ (ϝϯόɾจԽ)ʹԠͨ͡ͷΛબ͠·͠ΐ͏ʂ 19
https://github.com/ to4iki/Reader 20
Thanks 21