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
suspend-view-controller-sample
to4iki
0
3.2k
ケースに応じたUICollectionViewのレイアウト実装パターン
to4iki
1
4.6k
ビューインプレッションの計測方法
to4iki
1
1k
秘伝の `gitconfig`
to4iki
1
430
Abema iOS Architecture
to4iki
12
3.4k
timetable-bot
to4iki
0
14k
BLoC Pattern Introduction with Swift
to4iki
2
1.3k
nel
to4iki
0
140
[iOS] ビデオチームのスモールスクラム
to4iki
0
64
Featured
See All Featured
For a Future-Friendly Web
brad_frost
176
9.7k
Designing Experiences People Love
moore
141
24k
The World Runs on Bad Software
bkeepers
PRO
67
11k
The Cost Of JavaScript in 2023
addyosmani
49
7.7k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.5k
Scaling GitHub
holman
459
140k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.2k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2k
Code Review Best Practice
trishagee
67
18k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
5
520
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