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
110
Swift Concurrencyを利用したUIViewController表示の排他制御の実装
to4iki
0
3.4k
ケースに応じたUICollectionViewのレイアウト実装パターン
to4iki
1
5k
ビューインプレッションの計測方法
to4iki
1
1.1k
秘伝の `gitconfig`
to4iki
1
450
Abema iOS Architecture
to4iki
12
3.5k
timetable-bot
to4iki
0
14k
BLoC Pattern Introduction with Swift
to4iki
2
1.3k
nel
to4iki
0
160
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
53
7.8k
Faster Mobile Websites
deanohume
310
31k
A better future with KSS
kneath
239
18k
KATA
mclloyd
PRO
32
15k
4 Signs Your Business is Dying
shpigford
185
22k
Rebuilding a faster, lazier Slack
samanthasiow
84
9.2k
Building a Modern Day E-commerce SEO Strategy
aleyda
44
7.8k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.7k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
23
1.5k
Making Projects Easy
brettharned
120
6.4k
Done Done
chrislema
185
16k
How to Think Like a Performance Engineer
csswizardry
27
2.1k
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