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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Kenichi Yonekawa
November 20, 2016
Programming
19k
22
Share
iOSアプリの設計とDependency Injection
iOSオールスターズ2
https://eventdots.jp/event/602872
Kenichi Yonekawa
November 20, 2016
More Decks by Kenichi Yonekawa
See All by Kenichi Yonekawa
Fluxで複雑な状態の変化を予測可能にするiOSアプリ開発
yonekawa
9
43k
ネイティブアプリでもFluxしたい
yonekawa
0
2.3k
freeeモバイルチームの変遷と進化
yonekawa
0
9.6k
ReactiveCocoa Pitfalls at freee
yonekawa
2
880
RAC用クラス拡張の作り方
yonekawa
2
3k
Dive into Joybox
yonekawa
5
1.8k
Other Decks in Programming
See All in Programming
Technical Debt: Understanding it Rightly, Engaging it Rightly #LaravelLiveJP
shogogg
0
180
TypeSpec で繋ぐ複数プロダクトの型安全
maroon8021
1
270
プラグインで拡張される Context をtype-safe にする難しさと設計判断
kazupon
2
480
These Five Tricks Can Make Your Apps Greener, Cheaper, & Nicer
hollycummins
0
250
今さら聞けないCancellationToken
htkym
0
200
ユニットテストの先へ:テスト技法で要求・仕様を整理するJava開発実践 / Beyond_Unit_Testing_Practical_Java_Development_Techniques_for_Organizing_Requirements_and_Specifications
shimashima35
0
310
Moments When Things Go Wrong
aurimas
3
130
Composerを使ったサプライチェーン攻撃の様子を眺めてみる #phpstudy
o0h
PRO
2
190
Copilot CLI の継戦能力を高める コンテキスト管理
nozomutu
1
1.1k
Transactional Change Stream Processing With Debezium and Apache Flink
gunnarmorling
1
140
Oxcを導入して開発体験が向上した話
yug1224
4
260
AI時代の仕事技芸論 — ソフトウェア開発で「遊ぶように働く」職人的熟達のすすめ
kuranuki
1
530
Featured
See All Featured
It's Worth the Effort
3n
188
29k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
520
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
200
Ruling the World: When Life Gets Gamed
codingconduct
0
240
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
210
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.5k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.2k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
180
A Tale of Four Properties
chriscoyier
163
24k
The SEO identity crisis: Don't let AI make you average
varn
0
480
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
520
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/