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
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
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
800
Creating Composable Callables in Contemporary C++
rollbear
0
200
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
Performance Engineering for Everyone
elenatanasoiu
0
270
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
140
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
12
4.7k
act2-costs.pdf
sumedhbala
0
110
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
270
symfony/aiとlaravel/boost
77web
0
120
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
120
自作OSでスライド発表する
uyuki234
1
3.8k
Prismを使った型安全な暗号化_関数型まつり2026
_fhhmm
0
120
Featured
See All Featured
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.2k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
870
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
490
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
230
Design in an AI World
tapps
1
260
Bash Introduction
62gerente
615
220k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.5k
Why Our Code Smells
bkeepers
PRO
340
58k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
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