Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
モバイルアプリ開発に使える設計の話
Search
M.Inomata
November 16, 2018
Technology
1.7k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
モバイルアプリ開発に使える設計の話
iOS/Android開発をクリーンアーキテクチャで設計、開発する話です。
M.Inomata
November 16, 2018
More Decks by M.Inomata
See All by M.Inomata
20221005_AI勉強会
ecoopnet
0
610
20220112_AI勉強会
ecoopnet
0
590
AI最新論文読み会2021年11月
ecoopnet
0
390
AI最新論文読み会2021年5月
ecoopnet
0
590
AI最新論文読み会2020年12月
ecoopnet
0
470
AI最新技術Update会 8月
ecoopnet
0
530
医療ディープラーニング勉強会 DL勉強会 第3回 2020.4
ecoopnet
0
570
Kotlin Coroutines ことはじめ
ecoopnet
2
400
ハマった時に役立つ通信系デバッグの話
ecoopnet
3
1.9k
Other Decks in Technology
See All in Technology
go-sqletch
moznion
0
140
Local CI × GitHub Actions
gogutan
2
190
Webの常識が通じないHTMLメールのダークモード
teamlab
PRO
0
120
AI駆動開発の時代になったのでトヨタ生産方式から見直す
terurou
7
6k
実践! SRE × AI - ABEMA における AIOps -
tetsuya28
8
3.1k
宣言型部分更新は何を解決しどこへ向かうのか
shuta13
1
450
Rustuna: Rustによる高速なOptuna実装
pfn
PRO
0
190
フロントエンドカンファレンス関西2026 - 速すぎるUIに、待ち時間を
teamlab
PRO
0
130
JAWS-UGグッズ職人仕事の流儀
kentapapa
0
100
ストレスなくAIと付き合いたい!こんなときどうしてる?
namiki64
3
490
Browser Spec: Testing Hotwire with Ruby
takahashim
1
120
パスキーの自動テストはどこまでいけるのか
teamlab
PRO
0
200
Featured
See All Featured
For a Future-Friendly Web
brad_frost
184
10k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
940
Why Our Code Smells
bkeepers
PRO
340
58k
Writing Fast Ruby
sferik
630
63k
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
750
Reflections from 52 weeks, 52 projects
jeffersonlam
356
22k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
380
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
890
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Darren the Foodie - Storyboard
khoart
PRO
4
4k
Transcript
ϞόΠϧΞϓϦ։ൃʹ ͑Δઃܭͷ (iOS/Android)
ࣗݾհ גࣜձࣾ tech vein ද ழມ ॆԝ (͍ͷ·ͨ ΈͭͻΖ) ձࣾHP:
https://www.tech-vein.com/ private twitter: @ino2222
ձࣾ(tech vein)ͷհ 2013͔Β͋ΔେࡕຊொͷडୗγεςϜ։ൃձࣾͰ͢ɻ Android / iOS εϚʔτϑΥϯΞϓϦ։ൃɺ WebγεςϜ։ൃ(PHPɾJS)͕ಘҙͰ͢ɻ গਓͷٕज़తͳ͜ͱɾ໘ന͍͜ͱ͕͖ͳϝϯόʔ͕ू·ͬ ͯͰ͖ͨɺখ͞ͳձࣾͰ͢ɻ
ձ໊ࣾςοΫϕΠϯͱಡΈ·͢ɻ
ࣗࣾެ։தͷAndroid/iOSΞϓϦ ιϧΞϯϦʔγϡ ࣗͷΦϦΩϟϥΛ࡞ΔεϚϗ31( IUUQTPVOUFDIWFJODPN IUUQTCJUMZ);BV3 $IJJ2 ҬͰॿ͚߹͑Δಗ໊૬ஊΞϓϦ IUUQTBQQMFDP,[IYD ϙέοτΞϒετϥΫτ ҩྍैࣄऀ͚ͷ࠷৽δϟʔφϧߪಡΞϓϦ
ࠓͷςʔϚ ϞόΠϧΞϓϦ։ൃʹAndroid/iOSωΠςΟϒ։ൃʹ͓͚Δݸਓ తϕλʔͳઃܭʹ͍ͭͯɻ iOSத৺ɻAndroid։ൃʹ͍ͭͯҎԼͷΑ͏ʹಡΈସ͑ͯͩ͘ ͍͞ɻ ViewController(ུশVC) → Activity + Fragment
UIKitϑϨʔϜϫʔΫ → Android Framework ※Flutter, React Native, Xamarin ৮Ε·ͤΜɻ༻ޠΛஔ͖͑ͨΒԠ༻Ͱ͖Δͣɻ
ઃܭɾ࣮ͰΑ͋͘ΔΈ Fat ViewController (Fat Activity)ΛͳΜͱ͔ͨ͠ ͍ɻ MVC/MVVM/MVPΛ࠾༻͕ͨ͠ɺ࣮ऀʹΑͬͯ Ϟσϧͷ࣮ϧʔϧ͕ҧ͏ɻಛఆͷϞσϧ͕ංେԽ ͢ΔɻFatViewController vs
FatModel
ϞόΠϧΞϓϦͲͷઃܭ͕ ͍͍ͷ͔ ཚཱ͢ΔMVͳΜͱ͔ɻ MVC? MVP? MVVM? OSఏڙͷඪ४ϑϨʔϜϫʔΫ(UIKit)͕͋Δͷ ʹMVͳΜͱ͔ͳΜͯෆཁͳͷͰɻ
ΈͷղܾͷͨΊɺ ࠓճհ͢Δઃܭ(ΞʔΩςΫνϟ) • MVVM + ΫϦʔϯΞʔΩςΫνϟ • ิॿϥΠϒϥϦ: Rx, DI
Clean Architecture?
MVVM+Clean Architecture <Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU
seCase FetchTimelineU seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource ϓϨθϯ ςʔγϣϯ υϝΠϯ Πϯϑϥ
Clean Architectureͷجຊݪଇ • ΫϦʔϯͳઃܭʹ͢ΔͨΊͷϧʔϧɻ • ϏδωεϧʔϧɾσʔλΛத৺ͱͯ͠ɺUIɾAPIͳͲͷ ֎෦ΠϯλʔϑΣΠεΛϓϥάΠϯԽ͢Δɻ • ґଘؔΛ̍ํʹ͢Δɻ •
ͨͩ͠ৗʹଆ֎ଆΛΒͳ͍Α͏ʹඞཁʹԠͯ͡ґ ଘؔΛٯసͤ͞Δɻ • Λ·͙ͨࢀরΠϯλʔϑΣΠεΛܦ༝͢Δɻ
Clean Architectureͷݪଇʁ • ݪଇγϯϓϧͳϧʔϧͰɺMVʙͷΑ͏ͳɺಛఆͷΫϥεߏʹറΔ ͷͰͳ͍ɻ ———- • ݪଇΛकΕMVC, MVP, MVVM
ͳͲҙͷΞʔΩςΫνϟͱΈ߹Θ ͤͯΑ͍ɻ • Clean ArchitectureࣗମϋʔυΣΞ։ൃͳͲ͍͔ͳΔ։ൃͰద༻ Ͱ͖Δߟ͑ํͱͯ͠ఏএ͞Ε͍ͯΔɻ ˠ.77.ϕʔεͷ$MFBO"SDIJUFDUVSFΛ࠾༻
Clean Architecture ͷجຊ4 • ֎෦ΠϯλʔϑΣΠε (UIͱ͔DB, APIͱ͔) • ΠϯλʔϑΣΠεΞμϓλ •
Ϣʔεέʔε • ΤϯςΟςΟ(σʔλ) ͷ̐ɻ૿͑ͯݮͬͯOK͕ͩɺ ґଘؔඞͣकΔɻ
֎෦ΠϯλʔϑΣΠε(੨) • (OSϑϨʔϜϫʔΫؚΉ)ΞϓϦͷ֎ͷੈքͱͷ߹෦ɻ • ϢʔβʹݟͤΔUI෦ɻը໘ɾϏϡʔͷݟͨɺλοϓ ૢ࡞ͳͲͷΠϯλϥΫγϣϯɺ • ϋʔυΣΞɺWebAPIɺσʔλϕʔεͳͲɺΞϓϦ֎Ͱ ఆٛ͞ΕΔ֤छΠϯλʔϑΣΠε͕֘ɻ •
(ಉ͕ͩ͡ɺUIͱWebAPIɺWebAPIͱσʔλϕʔεͳͲ ผͷ֎෦ΠϯλʔϑΣΠεಉ͓࢜ޓ͍ΛΒͳ͍)
ΠϯλʔϑΣΠεΞμϓλ() • ֎෦ΠϯλʔϑΣΠεͱUseCaseͷؒͷ૬ޓ มΛߦ͏ɻ • ΠϯλʔϑΣΠεΞμϓλ੨(֎෦Πϯλʔ ϑΣΠε)ΛΒͳ͍ɻ
Ϣʔεέʔε() • ϏδωεϩδοΫΛهड़͢Δɻ • ̍ػೳ(ʹϢʔεέʔε)̍UseCaseΫϥεͱ͠ ࣮ͯݱ͢Δɻ • Ϣʔεέʔε(ΠϯλʔϑΣΠεΞμϓ λ)ɾ੨(֎෦ΠϯλʔϑΣΠε)ΛΒͳ͍ɻ
ΤϯςΟςΟɾσʔλ(ԫ) • ΞϓϦͰڞ௨ʹ͏σʔλΛఆٛ͢Δɻ • ΤϯςΟςΟଞͷΛҰΒͳ͍ɻ ˞%#ϨίʔυͷΤϯςΟςΟɺ"1*ϦΫΤετɾϨεϙϯεͳͲ ֎෦ΠϯλʔϑΣΠεґଘͷσʔλ͜͜ʹؚ·ͳ͍ɻ ֎෦ΠϯλʔϑΣΠεʹҐஔ͢Δ
ࣗΑΓ֎ΛΒͳ͍ ˒ҹͷ͖ ґଘͷํ ʹ <Interface> TimelineReposit ory <Data> Message MessageView
<UseCase> FetchTimelineU seCase FetchTimelineU seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource ࠨӈʹґଘ ࢀর ͍ͯ͠Δ ࠨӈΛܧঝ ࣮ ͍ͯ͠Δ
<Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU seCase FetchTimelineU
seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource ࣗΑΓ֎ΛΒͳ͍ 6*͕Δੈք <Data> Message MessageView TimelineView Controller <Interface> TimelineViewM odel <Data> User UI (ExternalInterface) Entity
<Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU seCase FetchTimelineU
seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource ࣗΑΓ֎ΛΒͳ͍ 7JFX.PEFM͕Δੈք <Data> Message <UseCase> FetchTimelineU seCase TimelineViewM odelImpl <Interface> TimelineViewM odel <Data> User ViewModel (InterfaceAdapter) Entity
ࣗΑΓ֎ΛΒͳ͍ 6TF$BTF͕Δੈք <Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU
seCase FetchTimelineU seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource <Interface> TimelineReposit ory <Data> Message <UseCase> FetchTimelineU seCase FetchTimelineU seCaseImpl <Data> User UseCase Entity
<Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU seCase FetchTimelineU
seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource ࣗΑΓ֎ΛΒͳ͍ &OUJUZ͕Δੈք <Data> Message <Data> User Entity
<Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU seCase FetchTimelineU
seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource ಉ͡֎෦ΠϯλʔϑΣΠε(੨)Ͱɺ ผͷ֎෦ΠϯλʔϑΣΠεಉ࢜ؔ͠ͳ͍ 5XJUUFS"1*ΫϥΠΞϯτɾ4%,͕Δੈք ☓ TwitterAPICli ent / SDK <Data> TwitterMessage <Data> TwitterUser TwitterAPI&SDK (ExternalInterface)
<Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU seCase FetchTimelineU
seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource ಉ͡Ξμϓλ()Ͱɺ ผͷ֎෦ΠϯλʔϑΣΠεಉ࢜ؔ͠ͳ͍ɻ %BUB4PVSDF͕Δੈք ☓ <Interface> TimelineReposit ory <Data> Message TwitterAPICli ent / SDK <Data> TwitterMessage <Data> User <Data> TwitterUser Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource ΠϯλʔϑΣΠεΞμϓλͷଘࡏҙٛɺ ͋͘·Ͱಛఆͷ֎෦ΠϯλʔϑΣΠεΛ6TF$BTFͰ ѻ͑ΔΠϯλʔϑΣΠε 3FQPTJUPSZ࣮ ʹม͢Δ͜ͱʹ͋Δɻ
͚ͩͲԿ͕خ͍͠ͷ͔ • ֎෦ΠϯλʔϑΣΠεͷࣄΛϢʔεέʔεʢϏδωεϩδο Ϋʣ͔ΒΓ͢ࣄ͕Ͱ͖Δɻ • ֎෦ΠϯλʔϑΣΠεͱϏδωεϩδοΫʢϢʔεʣέʔε ͓ޓ͍ʹਂ͘Βͳ͍··࣮Ͱ͖Δɻ • มߋͷӨڹ͕ہॴԽͰ͖ΔͷͰɺػೳՃࠩ͠ସ͕͑؆ ୯ɺ҆શʹͳΔɻ֎෦ΠϯλʔϑΣΠεΛ෦Խ(ϓϥάΠ
ϯԽ)Ͱ͖Δɻ • ෳਓͰ࡞ۀ͍͢͠ɻιʔείʔυ͕ԚΕʹ͍͘ʂ
֎ʹґଘ͠ͳ͍ ֎ʹରͯ͠ґଘ͕ͳ͍ ʹ֎ͷมߋʹ͍ͭͯɺ҆શ <Interface> TimelineReposit ory <Data> Message MessageView <UseCase>
FetchTimelineU seCase FetchTimelineU seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource <Interface> TimelineReposit ory <Data> Message <UseCase> FetchTimelineU seCase FetchTimelineU seCaseImpl <Data> User UseCase Entity <Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU seCase FetchTimelineU seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource <Data> Message <UseCase> FetchTimelineU seCase TimelineViewM odelImpl <Interface> TimelineViewM odel <Data> User ViewModel (InterfaceAdapter) Entity
ʹ࠷ݶ͔͠ґଘ͠ͳ͍ <Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU seCase
FetchTimelineU seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource <Interface> TimelineReposit ory <Data> Message <UseCase> FetchTimelineU seCase <Interface> TimelineViewM odel <Data> User Entity ʹରͯ͠ΠϯλʔϑΣΠεɾσʔλʹ͔͠ґଘ͠ͳ͍ ʹͷ෦มߋʹ͍ͭͯɺ֎҆શ
֎෦ΠϯλʔϑΣΠεͷมߋɾࠩ͠ସ͑ͷӨڹ ͕খ͍͞ <Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU
seCase FetchTimelineU seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource FacebookAPI Client / SDK <Data> FacebookMessa ge <Data> FacebookUser DataSource (InterfaceAdapter) FacebookAPI&SDK (ExternalInterface) FacebookAPI DataSource 5XJUUFSґଘΫϥε͕%BUB4PVSDF"1*ΫϥΠΞϯτ࣮ʹӅṭ͞Ε͍ͯΔͷͰɺ 5XJUUFSˠ'BDFCPPLʹมΘͬͯɺଞͷͷΫϥεΛҰม͑ͳͯ͘Α͍ɻ Өڹൣғ͚ͩ͜͜ʂˠ
<Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU seCase FetchTimelineU
seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource ϏδωεϩδοΫͷมߋ͕ ֎෦ΠϯλʔϑΣΠεɾUIʹӨڹ͠ͳ͍ ͨͱ͑ɺλΠϜϥΠϯͷϧʔϧɾ݅Λදࣔ͢ΔͳͲɻ ࣮ࡁ3FQPTJUPSZͷΈ߹ΘͤͰࡁΉͳΒɺ%BUB4PVSDF"1* 4%, ҎԼมߋෆཁɻ ݟͨͷมߋ͕ཁΒͳ͍ͳΒɺ7JFX.PEFM6*มߋෆཁɻ
<Interface> TimelineReposit ory <Data> Message MessageView <UseCase> FetchTimelineU seCase FetchTimelineU
seCaseImpl TimelineView Controller TimelineViewM odelImpl TwitterAPICli ent / SDK <Interface> TimelineViewM odel <Data> TwitterMessage <Data> User <Data> TwitterUser UI (ExternalInterface) ViewModel (InterfaceAdapter) UseCase Entity DataSource (InterfaceAdapter) TwitterAPI&SDK (ExternalInterface) TwitterAPIDat aSource TimelineDetailV iewModelImpl <Interface> TimelineDetailV iewModel TimelineDetail ViewController UIͷมߋ͕ ϏδωεϩδοΫɾσʔλ֎෦ΠϯλʔϑΣΠε ʹґଘ͠ͳ͍ ͨͱ͑ɺλΠϜϥΠϯͷݟͨͷมߋɺৄࡉը໘ՃͳͲɻ طଘ6TF$BTF͚ͩͰ࣮ݱͰ͖ΔͳΒɺϓϨθϯͷมߋ͚ͩͰࡁΉɻ
ΫϦʔϯΞʔΩςΫνϟͷΩϞ ੍ޚͷస(Inversion of Control) • ͜ΕͩͱɺϏδωεϩδοΫ͕֎෦ΠϯλʔϑΣΠεUIʹґଘͯ͠͠·͍ɺΫϦʔϯΞʔΩς ΫνϟͷઃܭϧʔϧΛकΕͳ͍ͷͰ͜͏͍ͨ͠ɻ TimelineViewM odel TimelineView
Controller FetchTimelineU seCase TwitterAPIDat aSource TwitterAPICli ent / SDK ґଘͷ͖Λస͍ͨ͠ ⇛ͦ͜Ͱ੍ޚͷస *P$ Λ׆༻͢Δʂ TimelineViewM odel TimelineView Controller FetchTimelineU seCase TwitterAPIDat aSource TwitterAPICli ent / SDK ͜͏ͳΔ • ૉʹ࣮͢ΔͱɺॲཧͷྲྀΕʹґଘؔʹͳΔɻ
• ྫɿTimelineUseCaseImpl ͔Β TimelineDataSource Λ͏ɻ ࣮ྫ(੍ޚͷసͳ͠) %BUB4PVSDFΫϥε 6TF$BTF*NQMΫϥεͰ%BUB4PVSDFར༻ ˢ%BUB4PVSDFʹ ɹɹґଘ͢ΔͷΛΊ͍ͨɻ
੍ޚͷస͋Γ 6TF$BTF*NQMΫϥεͷ֎͔Β%BUB4PVSDFΠϯελϯεΛ༩͑Δɻ ˢ֎෦͔ΒSFQPTJUPSZΠϯελϯε Λड͚औΔΑ͏ʹมߋɻ 6TF$BTF*NQM3FQPTJUPSZΠϯλʔ ϑΣΠε͔͠Βͳ͍Α͏ʹͳͬͨɻ ˢ6TF$BTF*NQMॳظԽ࣌ʹ %BUB4PVSDFΠϯελϯεΛࠩ͠ࠐΉɻ 6TF$BTF*NQMΫϥεͰ3FQPTJUPSZࢀর͢ΔΑ͏ʹͯ͠ɺ %BUB4PVSDFΠϯελϯεԽΛ͠ͳ͍ɻ
%BUB4UPSF͕3FQPTJUPSZΛܧঝ
੍ޚͷస FetchTimelineU seCaseImpl TwitterAPIDat aSource FetchTimelineU seCaseImpl FetchTimelineR epository TwitterAPIDat
aSource ͜Ε͕ɺ ͜͏ͳͬͨʂ %BUB4PVSDFΛΒͳ͍ ˠ5XJUUFS"1*%BUB4PVSDF͕ ೖΕସΘͬͯؾ͔ͮͳ͍ʂ
ˢ͜ͷΑ͏ʹ෦ͰΠϯλʔϑΣΠε͔͠Βͣɺ֎෦͔Β࣮ମΠϯελϯεΛೖ͢ ΔΈͷ͜ͱΛ%* %FQFOEFODZ*OKFDUJPOґଘؔͷೖ ͱݺͼ·͢ɻ %*ศརͳ໘ɺ࿈͢Δͱੜॲཧʢʹղܾʣ͕େมʹͳΓ͕ͪͰ͢ɻ ྫɿ"Λ࡞Δʹ#͕͍Δɺ#Λ࡞Δʹ$ͱ%͕͍Δʜ͔͠"͋ͪͪ͜Ͱ͏FUD ͦͷͨΊɺ%*Λ࿈తʹೖͯ͠ΠϯελϯεΛ࡞ͬͨΓอ࣋ͨ͠Γͯ͘͠ΕΔ ศརػߏΛ͏͜ͱ͕ଟ͍Ͱ͢ɻ ͦͷศརػߏͷ͜ͱΛɺ%*ίϯςφͱݺͼ·͢ɻ %*ίϯςφɺJ04ͳΒ4XJOKFDUɺ"OESPJEͳΒ%BHHFSΛ͍ͬͯ·͢ɻ
੍ޚͷసͱDIͱίϯςφ
DIղܾͷΠϝʔδ 7JFX.PEFM" 6TF$BTF" 6TF$BTF# %BUB4PVSDF" %BUB4PVSDF# 7JFX$POUSPMMFS" %BUB4PVSDF$ ҹશ෦ɺDIͰࠩ͠ࠐΜͰ࣮ݱ 6TF$BTF#
%BUB4PVSDF# %BUB4PVSDF$ 6TF$BTF#͕΄͚͠Ε %BUB4PVSDF# $͚ͩࠩ͠ࠐΈ
RxͰඇಉظॲཧͱଟஈॲཧΛָʹ ͢Δ • Rx=Reactive Extension ඇಉظॲཧͱಉظॲཧΛ۠ผͤͣετϦʔϜͱͯ͠εϚʔ τʹѻ͑ΔΑ͏ʹͳΔϥΠϒϥϦ(RxSwift / RxJava)ɻ •
ΫϦʔϯΞʔΩςΫνϟͷઃܭࢥͷϏδωεϩδοΫ ʹʮڥϥΠϒϥϦͷґଘΛͳ͘͢ʯͱ͠· ͕͢ɺ֤ͷग़ྗͱͯ͠RxΛ͏ͱָ࣮͕ʹͳΔͨ ΊΑ͘ར༻͍ͯ͠·͢ɻ ʢಛʹඇಉظपΓͱ֤Ͱͷσʔλมॲཧָ͕ʣ
RxΛͬͨྫ View͔ΒAPIऔಘͯ݁͠ՌΛදࣔ͢Δ·Ͱ TimelineViewM odel TimelineView Controller FetchTimelineU seCase TwitterAPIDat aSource
TwitterAPICli ent / SDK ը໘ϩʔυΠϕϯτ onLoad() execute() -> Observable<[Message]> fetchTimeline() -> Observable<[Message]> request() -> TwitterResponse response から Observable<[Message]> に 変換して結果を流す ObservableΛ ͦͷ··SFUVSO UJNFMJOFTϓϩύςΟΛ ࢹͯ͠6*࠶ඳը MFUUJNFMJOFT0CTFSWBCMF<.FTTBHF> ϓϩύςΟʹ݁ՌΛྲྀ͢ λΠϜϥΠϯऔಘͰ͖ͨΒ responseΛฦ͢
·ͱΊ • ࠓͲΜͳΞʔΩςΫνϟΛ͍ͬͯͯɺClean Architectureͷߟ͑ํΛΔ͜ͱϝϦοτʹͳΔ ͣɻ • ґଘΛ୯ํʹ͢ΔɺநԽͯ͠ૄ݁߹ʹ͢Δɺ੍ ޚΛసͯ͠֎෦ཁૉΛϓϥάΠϯԽ͢ΔɺͳͲɻ • ΫϦʔϯΞʔΩςΫνϟͷ͓ڙʹDIίϯςφɺRxΛ
Έ߹ΘͤΑ͏ɻ
ࢀߟαΠτɾॻ੶ IUUQTBN[OUP1XGP) $MFBO"SDIJUFDUVSFɹ ୡਓʹֶͿιϑτΣΞͷߏͱઃܭ ·ͩ.7$ .71 .77.Ͱফͯ͠ΔͷʁJ04$MFBO"SDIJUFDUVSFʹ͍ͭͯ IUUQTRJJUBDPNLPVUBMPVJUFNTBGDGBEFDED 5IF$MFBO"SDIJUFDUVSF IUUQTCMPHDMFBODPEFSDPNVODMFCPCUIFDMFBOBSDIJUFDUVSFIUNM
͍͞͝ʹ • tech vein Ͱ͜ΜͳΞϓϦΤϯδχΞɺ ϑϦʔϥϯεɾύʔτφʔ༷Λืू͍ͯ͠·͢ɻ • RxSwift, RxJava Λ͍͍ͨ
• MVVMɺ CleanArchitectureɺ DI Λ׆༻ͨ͠ઃܭʹڵຯ͕͋Δ ڵຯ͕͋ΔํɺͪΐͬͱΛฉ͍ͯΈ͍ͨํ ͨͩઃܭͷΛͬͱฉ͖͍ͨํ ͥͻ͓͕͚Լ͍͞ʂ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ 5XJUUFS!JOP
ิ:ଞͷΞʔΩςΫνϟͱClean Architecture ͷΈ߹Θͤʹ͍ͭͯ • ϓϨθϯςʔγϣϯUI+ViewModel͚ͩͰઆ໌͠·͕ͨ͠ɺΫϦʔϯ ΞʔΩςΫνϟͰറΓ͕ͳ͍෦ͳͷͰɺγεςϜن։ൃϝϯόʔ͕ ׳Ε͍ͯΔΞʔΩςΫνϟʹΑͬͯࣗ༝ʹબ͍͍ͯ͠ͱࢥ͍·͢ɻ • ྫɿ େن…ViewModelσʔλ͚ͩʹͯ͠ɺPresenterΛ༻ҙ͢Δ(Viper)
தن…ViewModelΛΘͣɺPresenter͚ͩ(MVP+CleanArchitecture) খن…ViewModelPresenterΘͳ͍(M+VC+CleanArchitecture) • ·ͨɺViewModelInterfaceͱ͠·͕ͨ͠ɺUIมߋʹӨڹΛड͚͍͍ͯͷ Ͱ͋ΕɺViewModelΠϯλʔϑΣΠεԽͤͣɺ࣮ମͷΈͰྑ͍ͱࢥ͍ ·͢ɻ(ϓϨθϯΛ̎Ͱͳ͚̍ͩ͘ͱΈͳ͢)
ิ:ΫϥεͷׂʢϓϨθϯʣ • ViewController / Activity ݸɿ̍ը໘ʢ̍෦ʣ̍Ϋϥεɻ ׂɿOSͷ੍ʹै͍ը໘දࣔ͢Δɻ • ViewModel ݸɿ1ը໘̍Ϋϥεɻڞ௨UI෦ʹͳ͍ͬͯΔ෦
ՃͰ̍෦(1View)1Ϋϥεɻ ׂɿUIͷΠϕϯτೖྗΛड͚͚ɺUIදࣔ͢Δσʔ λɾঢ়ଶΛอ࣋ɾग़ྗ͢Δ
ิ:ΫϥεͷׂʢυϝΠϯʣ • UseCase ݸɿ̍ػೳ̍Ϋϥεɻ ׂɿ̍ͭͷػೳΛ࣮ݱ͢Δ(ྫɿձһొ͢Δɺ͓ؾʹೖΓՃ͢Δ) • Repository ݸɿػೳΛߏ͢Δཁૉ܈ΛάϧʔϓԽͱͯ͠ɺ̍άϧʔϓ̍Ϋϥεɻ ׂɿUseCaseͷߏཁૉΛఏڙ͢Δɻ ྫɿձһใϦϙδτϦ…ձһใΛ࡞
/ ߋ৽ / আ͢Δ λΠϜϥΠϯϦϙδτϦ…λΠϜϥΠϯϦετऔಘɺݕࡧ݅ΛߜͬͯϦετऔಘɺ͓ؾʹೖΓ ϝοηʔδొ/আ ϝοηʔδߘϦϙδτϦ…ϝοηʔδૹ৴/আɺDMૹ৴/আ • ModelΦϒδΣΫτ(σʔλ) ݸɿ̍σʔλ୯Ґ̍Ϋϥε ׂɿϝοηʔδɺϢʔβͳͲͷσʔλΛͭγϯϓϧͳΦϒδΣΫτɻσʔλՃͷͨΊͷ؆୯ͳϝ ιουΛ࣋ͭ͜ͱɻ
ิ:ΫϥεͷׂʢΠϯϑϥʣ • DataSource ݸɿ̍֎෦ΠϯλʔϑΣΠε͋ͨΓ̍Ϋϥεɻ ׂɿಛఆͷWebAPIɺOSػೳɺDBͳͲΛૢ࡞͢ΔͨΊͷػೳΛ Repositoryཁ݅ʹ߹Θͤͯఏڙ͢ΔΫϥεɻ • Entity (֎෦ΠϯλʔϑΣΠεґଘ) ׂɿAPIϦΫΤετɺϨεϙϯεɺDBϨίʔυͳͲ֎෦ΠϯλʔϑΣΠ
ε͕ཁٻ͢Δσʔλܕ࣮ɻ͜ͷܕͷ··Repositoryʹ͍͚ͯ͠ͳ ͍ɻ • ͦͷଞ(DataStore͔ΒͷΈ͏) APIΫϥΠΞϯτϥΠϒϥϦɺDB࣮ΫϥεͳͲɻ
ิɿਤͰDataSource͕̎৭ʹ ͳ͍ͬͯͨͷ͕ؾʹͳΔ • ͜ͷDataSource֎෦ΠϯλʔϑΣΠε(੨)Λͬͯ͠·͍ͬͯΔՄೳੑ͕͋ΔͨΊɺ InterfaceAdapterͳ͠ͷ֎෦ΠϯλʔϑΣΠεͷΑ͏ͳҐஔ͚ͮʹͳΔͱߟ͑ศ্ٓ̎৭Ͱද͍ͯ͠· ͢ɻ • ࣮ࡍʹTwitterAPIClientͳͲ͕ϥΠϒϥϦʹΑͬͯநԽ͞Ε͍ͯΔ߹͋Γɺͦ͜ʹΠϯλʔϑΣ ΠεΛ͢ͱʹͳΓ·͢͠ɺͦ͏Ͱͳ͍߹ϏδωεϩδοΫͱRepositoryΠϯλʔϑΣΠε Ͱ҆શʹΓ͞Ε͍ͯΔͨΊɺ͜͜Ͱඞͣ͠ΠϯλʔϑΣΠεΛ৽ͨʹ༻ҙ͢Δඞཁͳ͍ͱߟ
͍͑ͯ·͢ɻ • ̐Ͱ࣮͢ΔͳΒDataSourceΠϯλʔϑΣΠεΞμϓλ()Ͱ͢ͷͰɺTwitterAPIClientͷinterface Λ༻ҙ͢Ε֎෦ΠϯλʔϑΣΠε(੨)ΛΒͳͯ͘Α͘ͳΓ·͢ɻ • ৗʹ͢Δͱ֎෦ΠϯλʔϑΣΠε༻ͷσʔλܕͷӅṭඞཁͳͷͰେมͰ͕͢ɺDataSource͕ෳ ࡶʹͳ͖ͬͯͯɺ֎෦ΠϯλʔϑΣΠεͱͷґଘΛബͨ͘͘͠ͳͬͨΒ͢Δ΄͏͕͍͍Ͱ͠ΐ͏ɻ DataSource (InterfaceAdapter) TwitterAPIDat aSource