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
Designable Archetecture
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
to4iki
October 17, 2017
Programming
110
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Designable Archetecture
WIP
to4iki
October 17, 2017
More Decks by to4iki
See All by to4iki
Claude Code の活用事例
to4iki
0
180
Swift Concurrencyを利用したUIViewController表示の排他制御の実装
to4iki
0
3.7k
ケースに応じたUICollectionViewのレイアウト実装パターン
to4iki
1
5.7k
ビューインプレッションの計測方法
to4iki
1
1.1k
秘伝の `gitconfig`
to4iki
1
470
Abema iOS Architecture
to4iki
12
3.6k
timetable-bot
to4iki
0
15k
BLoC Pattern Introduction with Swift
to4iki
2
1.4k
nel
to4iki
0
200
Other Decks in Programming
See All in Programming
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
継続モナドとリアクティブプログラミング
yukikurage
3
500
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
310
AIエージェントで 変わるAndroid開発環境
takahirom
2
550
えっ!!コードを読まずに開発を!?
hananouchi
0
190
SLOをサービス品質の共通言語にするために 取り組んできたこと
wakana0222
0
480
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
400
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
2
1.4k
1年で人数1.5倍、PR数5.5倍増。 品質とアウトカムはどうなったか、 何が効いたか
ike002jp
0
120
act2-costs.pdf
sumedhbala
0
110
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.4k
Featured
See All Featured
Building the Perfect Custom Keyboard
takai
2
810
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
460
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
360
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
290
Color Theory Basics | Prateek | Gurzu
gurzu
0
390
ラッコキーワード サービス紹介資料
rakko
1
3.9M
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
170
The Limits of Empathy - UXLibs8
cassininazir
1
460
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Bash Introduction
62gerente
615
220k
For a Future-Friendly Web
brad_frost
183
10k
Transcript
Designable Architecture Shinjuku.LT#13 @to4iki 1
Profile 4 @to4iki 4 iOS Developer ! 2
Agenda 4 Կނઃܭ͢Δͷ͔ 4 Ͳ͏ઃܭ͖͔͢ 4 ϞόΠϧʹ͓͚Δઃܭ 3
Կނઃܭ͢Δͷ͔ 4
୯७ͳΞϓϦέʔγϣϯ 4 શମ૾͕Ѳ͍͢͠ 4 1ਓͰಇ͘ͳΒɺԿΛߦ͏ͷ͔͙ʹѲͰ͖ Δ 5
ෳࡶͳΞϓϦέʔγϣϯ 4 શମ૾͕ҰʹѲͣ͠Β͍ 4 େͰಇ͘ͳΒɺ୭͔͕ԿΛ͍ͯ͠Δͷ͔Ѳ ͮ͠Β͍ 6
ෳࡶͳ֓೦Λ ׂͯ͠ཧ͍ͨ͠ 7
ෳࡶͳ֓೦ͷׂ 4 ը໘͝ͱ? 4 ػೳ͝ͱ? 4 ׂͷํ༷ʑͰɺ͜ΕΛܾΊΔͷ͕ઃܭ 8
ιϑτ(มߋ͕؆୯ͳ)ΣΞ() ϋʔυ(มߋ͕͍͠)ΣΞ() 9
ιϑτΣΞ "มߋ͕؆୯ʹͰ͖Δ" Α͏ʹ࡞Βͳ͚ΕͳΒͳ͍ 10
ͳͥઃܭ͢Δͷ͔ ؆୯ʹιϑτΣΞ ΛมߋͰ͖ΔΑ͏ɺ ෳࡶͳ֓೦Λׂ͠ ͍ͨ 11
Ͳ͏ઃܭ͖͔͢ 12
Presentation Domain Separation(PDS)1 4 UIʹؔΘΔͷͱɺͦΕҎ֎ͱͰׂ͠Α͏ 4 ͦΕҎ֎ = ڊେͳModelͱͯ͠Γग़͢ 1
https://martinfowler.com/bliki/PresentationDomainSeparation.html 13
PDSͷϝϦοτ 4 PresentationϩδοΫͱDomainϩδοΫ͕ ͔Ε͍ͯΔͱɺཧղ͍͢͠ 4 View͔Γ͍͢(HTML, JSON, ViewController) 4 UIςετ͕͠ʹ͍ͨ͘ΊɺͦΕΛ͢Δࣄ
ͰςετՄೳͳϩδοΫ෦ʹूதͰ͖Δ 14
PDSΛͲ͏࣮ݱ͢Δ͔ 15
࣮ݱํ๏ 4 MVW 4 MVC 4 MVP 4 MVVM 4
CleanArchitecture 4 Flux 4 etc 16
৭ʑ͋Δ 17
ϞόΠϧͷจ຺Ͱߟ͑ͯΈΔ = ϞόΠϧʹ͓͚Δઃܭ 18
બ͢Δʹ͋ͨͬ ͯ......Ͳ͏͍ͬͨ՝ ͕͋Δ͔Λੳ͢ Δ 19
ϞόΠϧ։ൃͷ՝(͍͠ ॴ) 1. APIͷϨεϙϯεΛͲͷΑ͏ʹViewʹө͢Δ ͔ 2. ෳࡶʹՄม͠͏Δσʔλͷঢ়ଶΛͲͷΑ͏ʹ Viewʹө͢Δ͔ 3. 1ͭͷσʔλมߋॲཧʹରͯ͠ෳͷModel͕
ؔ࿈͠߹͏ͷΛͲ͏ཧ͢Δ͔ 20
͜ΕΒͷΛղܾ ͢Δઃܭύλʔϯ͕ ཉ͍͠ʂ 21
1. APIͷϨεϙϯε ΛͲͷΑ͏ʹViewʹ ө͢Δ͔ 22
ex. Α͋͘Δ࣮ 4 RESTͷAPIͰ͋ΕϦιʔε୯ҐͰϨεϙϯ εʹ֘͢ΔΦϒδΣΫτΛ࡞ 4 ෳͷϦιʔεΛجʹը໘Λߏ͢ΔͷͰ͋Ε ɺͦΕΒΛݸผʹϦΫΤετ͠ඳը͢Δ 4 ඳը༻ͷModelʹม͢Δʁ
4 ͲͷϨΠϠʔͰߦ͏ʁͲͷΫϥε͕ͦΕΛ ߦ͏ʁ 23
24
ͭΒ͍ 25
ը໘୯ҐͷϨεϙϯεͩͬͨΒ ࡉ͔͍ࣄߟ͑ͳͯ͘ࡁΉͷͰ 26
27
ཧܗ 4 Read͕ϝΠϯͷΞϓϦͰ͋ΕɺσʔλΛͦ ͷ··Viewʹө͢Δ͚ͩͰΑ͍ͣ 4 APIଆͰ࠷దͳσʔλߏͰฦ͢ඞཁ͕͋Δ 4 ͘͠ΫϥΠΞϯτͰฒྻͰϦΫΤετ Λ͛ϖʔδใͱͯ͠ܗ͢Δ 28
29
ཧܗ 4 σʔλͷ࣋ͪํʹؔͯ͠ϨεϙϯεΛϖʔδ ใʹ࠷దԽͰ͖Εɺෳࡶͳෆཁ ʹͳΔ 4 Write͕ʹؔͯ͠ϑΥʔϜModelΛͲͷΑ͏ ʹͯ͠ӬଓԽ༻ͷModelʹม͢ΔʁReadͷ Modelͱಉ͡ߏʹ͢Δ?RͱWͷಉظ?ͳͲ ߟ͑Δ͜ͱ͕ଟ͍
=> ex. CQRS(ࠓճ۷ΓԼ͛ͳ͍ɺษڧ͠· 30
2. ෳࡶʹՄม͠͏ Δσʔλͷঢ়ଶΛͲ ͷΑ͏ʹViewʹө ͢Δ͔ 31
ex. Α͋͘Δ࣮ 4 खಈͰViewͷঢ়ଶͱσʔλΛಉظ͢Δ 4 ಉظͷॲཧ͕ࢄΒΓɺ͍ͭͲ͜ͰԿ͕Ͳ ͏มΘΔͷ͔͕༧ଌͮ͠Β͍ 4 DelegateύλʔϯʹΑΔ࣮ͩͱɺͲͷλΠ ϛϯάͰ࣮ߦ͞ΕΔͷ͔ͳͲ͕ݺͼग़͠ଆͱ࣮
ߦଆͰίʔυͷཧతͳڑ͕Ε͓ͯΓɺ Ѳ͢Δͷʹ͕͔͔࣌ؒΔ 32
ͭΒ͍ 33
MVVM 34
35
MVVM2 4 ViewModelViewͷͨΊͷঢ়ଶετΞ 4 ViewViewModelʹґଘ͠ɺViewModel Modelʹґଘ͢Δ(୯ํͷґଘ) 4 ViewϢʔβʔ͔ΒͷΞΫγϣϯΛड͚ͯɺ ͦͷΠϕϯτΛViewModelʹbind͢Δɻͦ͠ ͯͦͷbind͞ΕͨΠϕϯτʹΑͬͯ
2 https://speakerdeck.com/koutalou/manehuowadofalseshe-ji-hefalseapuroti 36
37
ViewModel 38
class SearchRepositoryViewModel { ... func fetchRepositories(with query: String) { //
obserberΛ४උ͢Δ isLoding.value = true let request = GitHubAPI.SearchRepositoriesRequest(query: query, page: 1) Session.shared.rx.send(request) .subscribe( onSuccess: { [unowned self] response in self.repositories.value += response self.isLoding.value = false }, onError: { [unowned self] (error) in self.isLoding.value = false // Τϥʔॲཧ }) .addDisposableTo(disposeBag) } } 39
View 40
class SearchRepositoryViewController: UIViewController { ... override func viewDidLoad() { super.viewDidLoad()
// UISearchBarͷೖྗΛߪಡ searchBar.rx.text.orEmpty.asDriver() .skip(1) .debounce(0.3) .distinctUntilChanged() .drive(onNext: { [unowned self] query in self.viewModel.fetchRepositories(with: query) }) .addDisposableTo(disposeBag) // ViewModelͷisLodingΛߪಡ viewModel.isLoding.asDriver() .drive(indicatorView.rx.isAnimating) .addDisposableTo(disposeBag) } } 41
MVVMͷخ͠͞ 4 σʔλ<->Viewͷಉظॲཧ͕ҰՕॴʹू͞ ΕͨࣄʹΑΓɺͲ͏͍ͬͨঢ়ଶͰͲͷΑ͏ͳৼ Δ͍Λߦ͏ͷ͔Ѳ͘͠ͳΔ 4 ViewModelදࣔʹؔ͢ΔϩδοΫ͚ͩɺUI ʹ͍ͭͯԿΒͳ͍ => ςελϏϦςΟ͕
ߴ͍ 42
3. σʔλมߋॲཧ ʹରͯ͠ෳͷ Model͕ؔ࿈͠߹͏ 43
ಥવͰ͕͢ɺ͜ͷΑ ͏ͳϢʔεέʔεΛ ߟ͑ͯΈ·͠ΐ͏ 44
45
MVVMͰ࣮ݱͯ͠ΈΔͱɺ 46
47
ͭΒΈ 4 ViewModel͕ෳͷModelΛࢀর͢Δ͜ͱʹ ͳΓɺґଘ͕ؔෳࡶʹͳΓ͏Δ 4 ͋Δఔͷنʹͳͬͯ͘Δͱʮෳͷը໘Ͱ σʔλΛڞ༗͍ͨ͠ʯʮAͷঢ়ଶΛBʹ͑ͨ ͍ʯͱ͍ͬͨΑ͏ͳʹ໘ 4 ઢෳࡶ
4 EventBus? NotificationManager? 48
ͭΒ͍ 49
Flux 50
Data in a Flux application flows in a single direction3
3 https://facebook.github.io/flux/docs/in-depth-overview.html#content 51
Flux(redux)ͷՁ 4 ୯ํͷσʔλϑϩʔΛڧ੍͢Δ 4 Single Store 52
struct CounterActionIncrease: Action {} struct CounterActionDecrease: Action {} class CounterViewController:
UIViewController, StoreSubscriber { ... @IBAction func increaseButtonTapped(sender: UIButton) { store.dispatch(CounterActionIncrease()) } 53
struct Store { // ActionʹԠͯ͡ঢ়ଶΛmutate // มߋΛdispatch(publish)͢Δ } class CounterViewController:
UIViewController, StoreSubscriber { ... // ߪಡ override func viewWillAppear(animated: Bool) { store.subscribe(self) } // storeʹมߋ͕͋ͬͨΒݺΕΔ func newState(state: AppState) { counterLabel.text = "\(state.counter)" } 54
MVC୯ํͷσʔλϑϩʔͷ ͣ ! 55
4 MVC + Observerύλʔϯ 4 Viewͷঢ়ଶͷྲྀΕΛ୯ํʹ͠ɺॲཧʹΑΔ ঢ়ଶͷมԽΛ༧ଌ͘͢͠ͳΔ 4 ͨͪͦΜͳҙਂ͘ͳ͍ɻ୯ํͷσʔλ ϑϩʔΛڧ੍͢Δͷ͕Fluxͷخ͠͞
4 View͕σʔλͷঢ়ଶΛࢹ͠ɺมߋ͋ͬͨΑ ͱ௨Λड͚औΓඳը͢͠ 4 ௨Λड͚औΓɺࠩඳը͢ΔͨΊʹ VirtualDOMͷΈΛ͍ͬͯΔ 56
Flux(redux)ͷՁ 4 ୯ํͷσʔλϑϩʔΛڧ੍͢Δ 4 Single Store 57
ݴ͍͑Εɺ Մมͳ Global Singleton 58
4 σʔλͷཧStoreʹͤɺActionͷΓ औΓʹΑͬͯͷΈσʔλΛߋ৽͢Δ 4 ετΞViewͰ͏σʔλΛڙڅ͢Δ 4 ετΞΛҰͭͷModelͱଊ͑Δ(PDSͷDͷ෦ ) 4 άϩʔόϧγϯάϧτϯ
4 ୯ҰͷετΞΛෳͷViewModelͰڞ༗ 4 ΞϓϦશମͷঢ়ଶΛѲ͍͢͠ 59
ΞϓϦશମͷঢ়ଶΛ ੍ޚԼʹ͓͚Δͷ ɺશೳײ͋Δʂ 60
ͱ͍͑ɺάϩʔόϧͳঢ়ଶม ͬͯͲ͏ͳͷʁ 4 StoreΛߋ৽Ͱ͖ΔͷStore͚ͩ 4 ΞΫγϣϯΛड͚औΓΓͷͳ͍ϝιο υΛݺͼग़͚ͩ͢ 4 ࢠͷετΞΛ࡞ׂ͢͠Δ 4
͜͜Λ୭͕ঢ়ଶΛߋ৽͢Δ͔ͳͲߏԽ͠ ͨͷ͕Redux 61
Store͕ࣗStoreΛߋ৽͢Δ 62
StoreͷߏԽ4 4 http://slides.com/jenyaterpil/redux-from-twitter-hype-to-production#/9 63
Storeͷׂํ๏ʹؔͯ͠ PDSͰ͍͏Domainͷઃܭʹͳ Δɻؤுͬͯ͜ ݸਓతʹ͜ͷྖҬϞό ΠϧͰෳࡶʹͳΒͳ͍ࣄ ͕ଟ͍ͱࢥ͏ 64
࠷ޙʹɺ ”ઃܭ”ͱ… 65
ઃܭ = ઓུ(త + ࢿݯ) 66
࠷খݶͷίετͰ྆ํຬͨ͢ͷ͕ ઃܭ ⭐ త(ചΕΔϓϩμΫτΛ࡞Δ) ⭐ ࢿݯ(࠷খݶͷϦιʔε) ઃܭɺArt(ࣗΑ͕Γͷͷ)Ͱͳ͘ Design(୭͔/Կ͔ͷͨΊʹߦ͏) 67
Conclusion 4 ͳͥઃܭ͢Δͷ͔: ෳࡶ͞Λղܾ͢ΔͨΊʹ 4 Ͳ͏ઃܭ͢Δͷ͔: ৭ʑ͋Δ(ࠓճPDSΛ հ) 4 ΞϓϦͰͲ͏ઃܭ͢Δͷ͔:
4 ඳըʹదͨ͠ϨεϙϯεΛ࡞Δ 4 σʔλ<->ViewͷಉظΛએݴతʹ(ex. MVVM/Flux) 68
De(൱ఆ)Sign(ϞϠϞϠ) ෳࡶͳͷΛ͖ͬ Γͤ͞Α͏ 69
See also ! Vue.jsͰ࣮ݱ͢ΔMVVMύλʔϯ FluxΞʔΩς Ϋνϟͱͷڑ http://techblog.reraku.co.jp/entry/ 2016/12/13/080000 ෳࡶͳJavaScriptΞϓϦέʔγϣϯʹཱ͔ͪ ͏ͨΊͷΞʔΩςΫνϟ
http://techblog.reraku.co.jp/entry/ 2017/08/08/184313 70
See also ! ϚωʔϑΥϫʔυͷઃܭͷΞϓϩʔν https://speakerdeck.com/koutalou/ manehuowadofalseshe-ji-hefalseapuroti 71