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
iOSアプリの設計とDependency Injection
Search
Kenichi Yonekawa
November 20, 2016
Programming
22
17k
iOSアプリの設計とDependency Injection
iOSオールスターズ2
https://eventdots.jp/event/602872
Kenichi Yonekawa
November 20, 2016
Tweet
Share
More Decks by Kenichi Yonekawa
See All by Kenichi Yonekawa
Fluxで複雑な状態の変化を予測可能にするiOSアプリ開発
yonekawa
9
20k
ネイティブアプリでもFluxしたい
yonekawa
0
2.3k
freeeモバイルチームの変遷と進化
yonekawa
0
7.8k
ReactiveCocoa Pitfalls at freee
yonekawa
2
850
RAC用クラス拡張の作り方
yonekawa
2
3k
Dive into Joybox
yonekawa
5
1.7k
Other Decks in Programming
See All in Programming
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
200
「ちょっと古いから」って避けてた技術書、今だからこそ読もう
mottyzzz
10
6.5k
Catch Up: Go Style Guide Update
andpad
0
210
非同期jobをtransaction内で 呼ぶなよ!絶対に呼ぶなよ!
alstrocrack
0
620
CSC509 Lecture 05
javiergs
PRO
0
300
CSC509 Lecture 01
javiergs
PRO
1
440
Things You Thought You Didn’t Need To Care About That Have a Big Impact On Your Job
hollycummins
0
210
ポスターセッション: 「まっすぐ行って、右!」って言ってラズパイカーを動かしたい 〜生成AI × Raspberry Pi Pico × Gradioの試作メモ〜
komofr
0
1.2k
Devvox Belgium - Agentic AI Patterns
kdubois
1
100
AI Coding Meetup #3 - 導入セッション / ai-coding-meetup-3
izumin5210
0
660
バッチ処理を「状態の記録」から「事実の記録」へ
panda728
PRO
0
140
monorepo の Go テストをはやくした〜い!~最小の依存解決への道のり~ / faster-testing-of-monorepos
convto
2
460
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
114
20k
We Have a Design System, Now What?
morganepeng
53
7.8k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.7k
Music & Morning Musume
bryan
46
6.8k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Java REST API Framework Comparison - PWX 2021
mraible
33
8.9k
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.6k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.5k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
6.1k
Automating Front-end Workflow
addyosmani
1371
200k
Transcript
@yonekawa J04ΞϓϦͷઃܭͱ %FQFOEFODZ*OKFDUJPO
None
None
None
None
%FQFOEFODZ*OKFDUJPO
Dependency? TUSVDU5XFFUFS\ GVODUXFFU UXFFU4USJOH \ MFUBQJ5XJUUFS"QJ BQJQPTU5XFFU UXFFU
^ ^ TUSVDU5XJUUFS"QJ\ GVODQPTU5XFFU UXFFU4USJOH \ MFUDPOGJH/463-4FTTJPO$POGJHVSBUJPOEFGBVMU4FTTJPO$POGJHVSBUJPO MFUTFTTJPO/463-4FTTJPO DPOGJHVSBUJPODPOGJH MFUSFRVFTUCVJMESFRVFTU TFTTJPOEBUB5BTL8JUI3FRVFTU SFRVFTU ^ ^ MFUUXFFUFS5XFFUFS UXFFUFSUXFFU )FMMP Tweeter TwitterApi HTTP Client
Dependency? TUSVDU5XFFUFS\ GVODUXFFU UXFFU4USJOH \ MFUBQJ5XJUUFS"QJ BQJQPTU5XFFU UXFFU
^ ^ TUSVDU5XJUUFS"QJ\ GVODQPTU5XFFU UXFFU4USJOH \ MFUDPOGJH/463-4FTTJPO$POGJHVSBUJPOEFGBVMU4FTTJPO$POGJHVSBUJPO MFUTFTTJPO/463-4FTTJPO DPOGJHVSBUJPODPOGJH MFUSFRVFTUCVJMESFRVFTU TFTTJPOEBUB5BTL8JUI3FRVFTU SFRVFTU ^ ^ MFUUXFFUFS5XFFUFS UXFFUFSUXFFU )FMMP Tweeter TwitterApi HTTP Client
Problem • TwitterApi͕௨৴ͷΓํʹґଘ͍ͯ͠Δɻ௨৴ͷΓํΛ ม͔͑ͨͬͨΒTwitterApiಉ࣌ʹม͑ͳ͍ͱ͍͚ͳ͍ɻ • ʮπΠʔτΛߘ͢ΔʯλεΫʹؔͷͳ͍ॳظԽॲཧ͕ଟ ͘ͳΓϝιουͷؔ৺ࣄ͕૿͑Δ • ௨৴ͷίʔυ͕ີ݁߹͍ͯ͠ΔͨΊpostTweetͷςετ͕ॻ ͖ͮΒ͍
Solution TUSVDU5XFFUFS\ MFUBQJ5XJUUFS"QJ GVODUXFFU UXFFU4USJOH \ BQJQPTU5XFFU UXFFU ^
^ TUSVDU5XJUUFS"QJ\ MFUIUUQ$MJFOU)551$MJFOU GVODQPTU5XFFU UXFFU4USJOH \ MFUSFRVFTUCVJMESFRVFTU IUUQ$MJFOUTFOE SFRVFTU ^ ^ MFUBQJ5XJUUFS"QJ IUUQ$MJFOU)UUQ$MJFOU8JUI63-4FTTJPO MFUUXFFUFS5XFFUFS BQJBQJ UXFFUFSUXFFU )FMMP
Solution TUSVDU5XFFUFS\ MFUBQJ5XJUUFS"QJ GVODUXFFU UXFFU4USJOH \ BQJQPTU5XFFU UXFFU ^
^ TUSVDU5XJUUFS"QJ\ MFUIUUQ$MJFOU)551$MJFOU GVODQPTU5XFFU UXFFU4USJOH \ MFUSFRVFTUCVJMESFRVFTU IUUQ$MJFOUTFOE SFRVFTU ^ ^ MFUBQJ5XJUUFS"QJ IUUQ$MJFOU)UUQ$MJFOU8JUI63-4FTTJPO MFUUXFFUFS5XFFUFS BQJBQJ UXFFUFSUXFFU )FMMP
Dependency Injection Pattern • ίϯϙʔωϯτͷؒͷґଘؔΛιʔείʔυ͔Βഉআ͠ɺ ֎෦͔ΒೖͰ͖ΔΑ͏ʹ͢ΔσβΠϯύλʔϯ • ίϯϙʔωϯτ͔ΒΠϯελϯεͷੜͦͷ۩ମతͳ࣮ ͱ͍ͬͨຊདྷඞཁͳ͍ؔ৺ࣄ͕औΓআ͔Ε࣮͕ͯγϯϓϧ ʹͳΔ
• ֎෦͔Βίϯϙʔωϯτͷ࣮Λ੍ޚͰ͖ΔͷͰɺ௨৴෦ ͚ͩϞοΫͨ͠ΓϢχοτςετ͕Γ͘͢ͳΔ
Problem • Tweeter͕૿͑ͨΒຖճTwitterApiͱHTTP ClientΛॳظԽ͠ ͔ͯͯ͠Βݺͼग़͞ͳ͍ͱ͍͚ͳ͍ • ࠶ར༻͢ΔͨΊʹίϯϙʔωϯτԽͯ͠ΔͷʹͦΕΛ͏ͨ Ίͷ४උ͕ଟ͘ͳͬͯ໘͍͘͞
DI Container • ґଘίϯϙʔωϯτͷੜͱೖΛผͷίϯϙʔωϯτʹ ͤΔɻDIίϯςφͱ͔DIϑϨʔϜϫʔΫͱݺΕΔͷ • ίϯςφίϯϙʔωϯτͷੜํ๏ͱೖํ๏Λ͍ͬͯ ͯɺίϯϙʔωϯτؒͷґଘؔΛղܾͯ͠ΦϒδΣΫτΛ ฦͯ͘͠ΕΔ DI
Container Client Code Tweeter TwitterApi HTTP Client
Pseudocode SFHJTUFS )551$MJFOUTFMG \ )551$MJFOUJO SFUVSO)UUQ$MJFOU8JUI63-4FTTJPO ^ SFHJTUFS 5XJUUFS"QJTFMG
\ 5XJUUFS"QJJO MFUVSM4FTTJPODPNQPOFOU /463-4FTTJPOTFMG SFUVSO5XJUUFS"QJ VSM4FTTJPOVSM4FTTJPO ^ SFHJTUFS 5XFFUFSTFMG \ 5XFFUFSJO MFUBQJDPNQPOFOU 5XJUUFS"QJTFMG SFUVSO5XFFUFS BQJBQJ ^ MFUUXFFUFSDPNQPOFOU 5XFFUFSTFMG UXFFUFSUXFFU )FMMP
Pseudocode SFHJTUFS )551$MJFOUTFMG \ )551$MJFOUJO SFUVSO"MBNPGJSF$MJFOU ^ SFHJTUFS 5XJUUFS"QJTFMG
\ 5XJUUFS"QJJO MFUVSM4FTTJPODPNQPOFOU /463-4FTTJPOTFMG SFUVSO5XJUUFS"QJ VSM4FTTJPOVSM4FTTJPO ^ SFHJTUFS 5XFFUFSTFMG \ 5XFFUFSJO MFUBQJDPNQPOFOU 5XJUUFS"QJTFMG SFUVSO5XFFUFS BQJBQJ ^ MFUUXFFUFSDPNQPOFOU 5XFFUFSTFMG UXFFUFSUXFFU )FMMP
Clean Architecture • ϩδοΫͷͱׂΛׂ͢Δ͜ͱͰͦΕͧΕͷΛ໌ ֬ʹͯ͠ઃܭͷڞ௨ೝࣝΛ࡞ΔΞʔΩςΫνϟઃܭ • ׂΛׂͤ͞ΔʹͦΕͧΕͷίϯϙʔωϯτͷґଘؔ ΛΓ͢ඞཁ͕͋Δ • Clean
ArchitectureDIΛੵۃతʹ׆༻ͨ͠ʢ׆༻Ͱ͖Δʣ ΞʔΩςΫνϟ
%*'SBNFXPSLGPSJ04
Typical DI Frameworks • Typhoon • Swinject • Cleanse
Typhoon • Objective-C͔࣌Β͋ΔฮͷDIίϯςφ • Storyboard͔ΒͷΠϯελϯεੜαϙʔτɺplistͰͷґ ଘؔͷఆٛͳͲػೳ๛ • ࣮͕Objective-Cϕʔεͷ͍͔ͤSwiftͩͱܕͷѻ͍͕͋· Γ͏·͘ͳ͍
Swinject • Pure SwiftͰॻ͔ΕͨDIϑϨʔϜϫʔΫ • ContainerΦϒδΣΫτʹܕͱBlockΛొͯ͠ܕΛىʹґ ଘΛղܾ͢Δ • Typhoonͱҧ͍ɺຊମʹೖΕͨ͘ͳ͍͕ศརͳػೳ֦ு ͷܗͰఏڙ͍ͯ͠Δɻ
Swinject Style MFUDPOUBJOFS$POUBJOFS DPOUBJOFSSFHJTUFS "OJNBM5ZQFTFMG \@JO$BU OBNF.JNJ ^ DPOUBJOFSSFHJTUFS
1FSTPO5ZQFTFMG \SJO 1FU0XOFS QFUSSFTPMWF "OJNBM5ZQFTFMG ^ MFUQFSTPODPOUBJOFSSFTPMWF 1FSTPO5ZQFTFMG QFSTPOQMBZ
Cleanse • SquareͷDIίϯςφ • SwinjectͷContainerʹ૬͢Δͷແ͘ɺComponentͱ ModuleͷΈ߹ΘͤͰ֤ΦϒδΣΫτͷґଘΛཧ͢Δ • JavaͷDIϑϨʔϜϫʔΫ(Dagger)ʹΠϯεύΠΞ͞Ε͍ͯ ΔͷͰ༻ޠࣅ͍ͯΔ͕ɺSwiftͷݴޠ༷ʹ߹Θͤͯઃܭ ͞Ε͍ͯΔ
Cleanse Style TUSVDU"OJNBM.PEVMF$MFBOTF.PEVMF\ GVODDPOGJHVSF##JOEFS CJOEFSCJOEFS# \ CJOEFSCJOE "OJNBM5ZQFTFMG UP WBMVF$BU
OBNF.JNJ ^ ^ TUSVDU0XOFS$PNQPOFOU$MFBOTF$PNQPOFOU\ UZQFBMJBT3PPU1FSTPO5ZQF GVODDPOGJHVSF##JOEFS CJOEFSCJOEFS# \ CJOEFSJOTUBMM NPEVMF"OJNBM.PEVMF CJOEFSCJOE 1FSTPO5ZQFTFMG UP GBDUPSZ1FU0XOFSJOJU ^ ^ MFUQFSTPOUSZ0XOFS$PNQPOFOU CVJME QFSTPOQMBZ
Swinject vs Cleanse • CleanseίϯϙʔωϯτఆٛͰΔ͜ͱ͕ଟ͍ͷͰ࠷ॳ ໘ɻSwinjectContainerʹܕͱBlockΛ͚ͩ͢Ͱ͍͍ͷ ͰΧδϡΞϧʹ͑Δɻ • ίϯϙʔωϯτͷੜํ๏Λίϯϙʔωϯτ୯ҐͰఆٛ͢ ΔCleanseͷ΄͏͕ΠϯλϑΣʔεͱͯ͠ے͕Αͦ͞͏ɻ
SwinjectContainerͷཧͱ͍͏ผͷ͕͋Δɻ • Cleanse·ͩbetaͰ͋·ΓίϛϡχςΟͷಈ͖͕ͳ͍
J04%*1SBDUJDF
Protocol Oriented • ίϯϙʔωϯτؒΛૄ݁߹ʹ͢ΔʹίϯϙʔωϯτͷΠ ϯλϑΣʔεΛ໌ࣔతʹ͠ͳ͍ͱ͍͚ͳ͍ɻΠϯλϑΣʔε ͕ಉ͡ͳΒ࣮ͷࠩ͠ସ͕͑༰қʹͳΔɻ QSPUPDPM)551$MJFOU\ GVODTFOE ^
DMBTT/463-4FTTJPO$MJFOU)551$MJFOU\ GVODTFOE \ /463-4FTTJPO EBUB5BTL8JUI3FRVFTU ǘ ^ ^ DMBTT"MBNPGJSF$MJFOU)551$MJFOU\ GVODTFOE \ "MBNPGJSFSFRVFTU ǘ ^ ^
Constructor Injection vs Property Injection • Property Injection֎෦ʹϓϩύςΟΛެ։͢Δඞཁ͕͋ ΓMutableʹ͠ͳ͍ͱ͍͚ͳ͍ͷͰجຊతʹConstructor InjectionΛ͓קΊ͍ͨ͠
• CleanseͷυΩϡϝϯτͰProperty Injection AppDelegateStoryboardͳͲΠϯελϯεੜΛ੍ޚͰ ͖ͳ͍έʔεͰ͏ͱ͞Ε͍ͯΔ
prepareForSegue • ભҠݩͷViewController͕ભҠઌͷViewControllerʹ͍ͭͯ Βͳ͍ͱ͍͚ͳ͍ɻભҠઌͷ༷͕มΘͬͨΒભҠݩΛ ͞ͳ͍ͱ͍͚ͳ͍ɻ • ΠϯελϯεԽStoryboardʹΑͬͯߦΘΕΔͷͰ PropertyInjectorΛͬͯೖ͢Δ PWFSSJEFGVODQSFQBSF'PS4FHVF TFHVF6*4UPSZCPBSE4FHVF
TFOEFS "OZ0CKFDU \ JGMFUWDTFHVFEFTUJOBUJPO7JFX$POUSPMMFSBT /FYU7JFX$POUSPMMFS\ MFUJOKFDUPSUSZ/FYU7JFX$POUSPMMFS$PNQPOFOU CVJME JOKFDUPSJOKFDU1SPQFSUJFT JOUPWD ^ ^
DI with arguments • ΠϯελϯεੜΛίϯςφʹͤͯ͠·͏ͷͰɺϢʔβʔ ೖྗͳͲͷಈతͳύϥϝʔλͲ͏͖͔͢ • CleanseComponentFactoryͱ͍͏ػೳͰͦΕΛ࣮ݱͰ͖ Δ͕·ͩ։ൃதɻݱঢ়ͰComponentͷॳظԽ࣌ʹύϥ ϝʔλΛͯ͠Moduleͷੜʹ͏͔͠ͳͦ͞͏
• SwinjectґଘΦϒδΣΫτΛresolve͢Δ࣌ʹੜίʔυ ͷύϥϝʔλ͕ͤΔ
DI with arguments (Cleanse) TUSVDU/FYU7JFX$PNQPOFOU$MFBOTF$PNQPOFOU\ MFUJUFN*UFN UZQFBMJBT3PPU1SPQFSUZ*OKFDUPS/FYU7JFX$POUSPMMFS GVODDPOGJHVSF##JOEFS CJOEFSCJOEFS# \
CJOEFSJOTUBMM NPEVMF7JFX.PEFM.PEVMF CJOEFS CJOE1SPQFSUZ*OKFDUJPO0G /FYU7JFX$POUSPMMFSTFMG UP\ WD/FYU7JFX$POUSPMMFS WJFX.PEFM7JFX.PEFM JO WJFX.PEFMJUFNJUFN WDWJFX.PEFMWJFX.PEFM ^ ^ ^ PWFSSJEFGVODQSFQBSF'PS4FHVF TFHVF6*4UPSZCPBSE4FHVF TFOEFS"OZ0CKFDU \ JGMFUWDTFHVFEFTUJOBUJPO7JFX$POUSPMMFSBT /FYU7JFX$POUSPMMFS\ MFUJUFN MFUJOKFDUPSUSZ/FYU7JFX$PNQPOFOU JUFNJUFN CVJME JOKFDUPSJOKFDU1SPQFSUJFT JOUPWD ^ ^
DI with arguments (Cleanse) TUSVDU/FYU7JFX$PNQPOFOU$MFBOTF$PNQPOFOU\ MFUJUFN*UFN UZQFBMJBT3PPU1SPQFSUZ*OKFDUPS/FYU7JFX$POUSPMMFS GVODDPOGJHVSF##JOEFS CJOEFSCJOEFS# \
CJOEFSJOTUBMM NPEVMF7JFX.PEFM.PEVMF CJOEFS CJOE1SPQFSUZ*OKFDUJPO0G /FYU7JFX$POUSPMMFSTFMG UP\ WD/FYU7JFX$POUSPMMFS WJFX.PEFM7JFX.PEFM JO WJFX.PEFMJUFNJUFN WDWJFX.PEFMWJFX.PEFM ^ ^ ^ PWFSSJEFGVODQSFQBSF'PS4FHVF TFHVF6*4UPSZCPBSE4FHVF TFOEFS"OZ0CKFDU \ JGMFUWDTFHVFEFTUJOBUJPO7JFX$POUSPMMFSBT /FYU7JFX$POUSPMMFS\ MFUJUFN MFUJOKFDUPSUSZ/FYU7JFX$PNQPOFOU JUFNJUFN CVJME JOKFDUPSJOKFDU1SPQFSUJFT JOUPWD ^ ^
Mock Testing • API௨৴෦ͳͲΛϢχοτςετͷ࣌ʹϞοΫ࣮ʹࠩ ͠ସ͍͑ͨɻ • CleanseModuleΛOverride͢Δ͜ͱ͕Ͱ͖ΔͷͰϞοΫ ࣮ͱͷࠩ͠ସ͕͑༰қ͚ͩͲɾɾɾ TUSVDU'BLF.PEVMF0WFSSJEF.PEVMF\ UZQFBMJBT0WFSSJEFT5XFFUFS$PNQPOFOU
GVODDPOGJHVSF##JOEFS CJOEFSCJOEFS# \ CJOEFSJOTUBMM NPEVMF'BLF5XJUUFS"QJ.PEVMF ^ ^ JGVTF'BLF.PEF\ JOKFDUPSUSZ$PNQPOFOU XJUI0WFSSJEFT PWFSSJEF.PEVMF'BLF.PEVMF CVJME ^FMTF\ JOKFDUPSUSZ$PNQPOFOU CVJME ^
Do Not Use Fake Mode • ίϯϙʔωϯτఆٛΛ্ॻ͖͢Δͷίϯϙʔωϯτؒͷґଘͷ ࿈ΛಡΈͮΒ͘͢ΔͷͰΑ͘ͳ͍ʢCleanseͰ͜ͷػೳΛ আ͢ΔPR͕ग़ͯΔʣ •
ૉʹϢχοτςετ࣌ʹϞοΫ͢Δ͖ɻґଘΦϒδΣΫτ ԿΒ͔ͷܗͰ֎෦͔ΒͤΔઃܭʹͳ͍ͬͯΔ͔Β؆୯ͳͣ DMBTT5XJUUFS"QJ5FTUT9$5FTU$BTF\ WBSTVCKFDU5XJUUFS"QJ MFUTFTTJPO.PDL63-4FTTJPO PWFSSJEFGVODTFU6Q \ TVQFSTFU6Q TVCKFDU5XJUUFS"QJ TFTTJPOTFTTJPO ^ ^
Swiftʹ͓͚Δݱ࣮తͳϞοΫ https://realm.io/jp/news/tryswift-veronica-ray-real-world-mocking-swift/
·ͱΊ
·ͱΊ • ෳࡶͳΞϓϦͰมߋʹڧ͍ΞʔΩςΫνϟΛ࡞ΔͨΊʹ· ͣɺίϯϙʔωϯτؒͷґଘΛഉআ͢Δ͜ͱ͕ॏཁɻDIʹ ΑͬͯͦͷΛ࡞Δ͜ͱ͕Ͱ͖Δ • SwiftͷProtocolܕγεςϜΛ͏·ͬͨ͘DIϑϨʔϜϫʔ ΫΛ࠾༻͢ΔͱΞϓϦέʔγϣϯ͕ΑΓݎ࿚ʹͳΔ • ͍·ϓϩμΫγϣϯʹೖΕΔͳΒSwinject͕Αͦ͞͏͕ͩɺ
CleanseΠϯλϑΣʔε͕Α͘Ͱ͖͍ͯΔͷͰظ͍ͨ͠
Improving Existing Apps with Modern Best Practices https://developer.apple.com/videos/play/wwdc2016/213/