Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
ペイモのアーキテクチャ
Shuichi Nagao
February 19, 2018
Programming
0
530
ペイモのアーキテクチャ
割り勘アプリのアーキテクチャについての発表です。
Shuichi Nagao
February 19, 2018
Tweet
Share
More Decks by Shuichi Nagao
See All by Shuichi Nagao
UX for Key Management
ngo275
0
34
深センではテクノロジーを使う人がイノベーションを起こしている
ngo275
0
300
スマートコントラクトのデプロイって何だろう
ngo275
0
480
プロトタイピングするならFirebaseを使ってみよう
ngo275
0
1.5k
Ethereumで開発を始めるなら知っておきたいこと
ngo275
11
4.2k
スマートコントラクトをHTTPで実行する
ngo275
0
62
EOSでスマートコントラクトを実行してみる
ngo275
0
1.1k
iOSアプリエンジニアがReact Nativeを使ってみて
ngo275
0
250
中東のシリコンバレーことイスラエルに行ってきた
ngo275
0
90
Other Decks in Programming
See All in Programming
Jakarta EE 10 - Feature by Feature with My Open Source Journey
ivargrimstad
0
1.9k
PythonユーザによるRust入門
rmizuta3
9
3k
個人開発でReact Native + Expo製アプリを作った話
ryonakae
1
440
heyにおけるCI/CDの現状と課題
fufuhu
1
540
Java アプリとAWS の良い関係 - AWS でJava アプリを実行する一番簡単な方法教えます / AWS for Javarista
kanamasa
2
1.1k
io22 extended What's new in app performance
veronikapj
0
330
Amazon ECSのネットワーク関連コストの話
msato
0
610
Branching out to Jetpack Compose
chrisbanes
4
1.1k
React NativeアプリにStorybook CSF3.0を導入しよう
texmeijin
0
150
IE Graduation Certificate
jxck
6
4.7k
開発速度を5倍早くするVSCodeの拡張機能を作った
purp1eeeee
2
130
I/O Extended 2022 in Android ~ Whats new in Android development tools
pluu
0
520
Featured
See All Featured
Building an army of robots
kneath
299
40k
VelocityConf: Rendering Performance Case Studies
addyosmani
316
22k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
15
940
Ruby is Unlike a Banana
tanoku
91
9.2k
The Invisible Customer
myddelton
110
11k
Unsuck your backbone
ammeep
659
55k
The Power of CSS Pseudo Elements
geoffreycrofte
46
3.9k
Rails Girls Zürich Keynote
gr2m
86
12k
Building Flexible Design Systems
yeseniaperezcruz
310
34k
What's in a price? How to price your products and services
michaelherold
229
9.4k
For a Future-Friendly Web
brad_frost
166
7.4k
Rebuilding a faster, lazier Slack
samanthasiow
62
7.2k
Transcript
ϖΠϞͷΞʔΩςΫνϟ @NGO275 1
AGENDA ࠓ͢͜ͱ ▸ ΫϦʔϯΞʔΩςΫνϟͱ ▸ ϖΠϞͷΞʔΩςΫνϟ֓؍ ▸ ϖΠϞͷ࣮ࡍͷϦϑΝΫλྫ ▸ ·ͱΊ
2
WHAT IS CLEAN ARCHITECTURE? ΫϦʔϯΞʔΩςΫνϟͱ 3
WHAT IS CLEAN ARCHITECTURE? ΞϓϦ։ൃ͋Δ͋Δ ▸ ϏδωεϩδοΫ͕ͩΜͩΜΘ͔Βͳ͘ͳΔ ▸ ೖग़ྗͷॲཧ͕ࢄࡒͯ͠ॲཧΛ͏ͷ͕େมʹͳΔ ▸
ঢ়ଶΛ࣋ͭͷ͕૿Ճͯ͠෭࡞༻Λଟ͘ੜΜͰ͠·͏ 4
WHAT IS CLEAN ARCHITECTURE? ղܾ͍ͨ͜͠ͱ ▸ ϏδωεϩδοΫΛ໌֬ʹ͍ͨ͠ ▸ ϑϨʔϜϫʔΫ͔Βಠཱ͢Δ ▸
ϏδωεϩδοΫετΞ͔Βಠཱ͢Δ ▸ ϏδωεϩδοΫUI͔Βಠཱ͢Δ ▸ ϏδωεϩδοΫΛςετ͘͢͠Δ 5
WHAT IS CLEAN ARCHITECTURE? ղܾํ๏ Πϝʔδਤ https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html 6
PAYMO ARCHITECTURE ϖΠϞͷΞʔΩςΫνϟ֓؍ 7
PAYMO ARCHITECTURE ϦϦʔεॳͷϖΠϞͷΞʔΩςΫνϟΠϝʔδ ▸ View͕Ͱ͔͘ɺPresenterͱUseCase΄΅ۭͬΆ ▸ DataStore͕গʑେ͖͍ ▸ ϩδοΫ͕ViewDataStoreʹॻ͍ͯ͋ͬͨ ▸
1݄ࠒ 8
PAYMO ARCHITECTURE ϦϦʔεॳͷϖΠϞͷΞʔΩςΫνϟΠϝʔδ ▸ View͕Ͱ͔͘ɺPresenterͱUseCase΄΅ۭͬΆ ▸ DataStore͕গʑେ͖͍ ▸ ϩδοΫ͕ViewDataStoreʹॻ͍ͯ͋ͬͨ ▸
1݄ࠒ 9
PAYMO ARCHITECTURE վળޙͷϖΠϞͷΞʔΩςΫνϟΠϝʔδᶃ ▸ PresenterʹUIϩδοΫҠߦ ▸ 7݄ࠒ 10
PAYMO ARCHITECTURE վળޙͷϖΠϞͷΞʔΩςΫνϟΠϝʔδᶃ ▸ PresenterʹUIϩδοΫҠߦ ▸ 7݄ࠒ 11
PAYMO ARCHITECTURE վળޙͷϖΠϞͷΞʔΩςΫνϟΠϝʔδᶄ ▸ ϏδωεϩδοΫΛUseCaseʹҠߦ ▸ 10݄ࠒ 12
PAYMO ARCHITECTURE վળޙͷϖΠϞͷΞʔΩςΫνϟΠϝʔδᶄ ▸ ϏδωεϩδοΫΛUseCaseʹҠߦ ▸ 10݄ࠒ 13
PAYMO REFACTORING ϖΠϞͷ࣮ࡍͷϦϑΝΫλྫ 14
TIMELINE ’S VIEWCONTROLLER REFACTORING func displayShiharaiItem(item: ShiharaiItem, indexPath: IndexPath) ->
TimelineTableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier, for: indexPath) as! TimelineTableViewCell let name: String guard let date = item.createdAt else { return cell } switch item.status { case .accepted: if (ࢧ͍͕ࣗ) { // ඳըͷͨΊͷॲཧ } else { // ඳըͷͨΊͷॲཧ } cell.mainLabel.attributedText = … case .rejected: if (ࢧ͍͕ࣗ) { if item.merchant == nil{ // ඳըͷͨΊͷॲཧ } else { // ඳըͷͨΊͷॲཧ } } else { // ඳըͷͨΊͷॲཧ } // ඳըͷͨΊͷॲཧ case .requested: if (ࢧ͍͕ࣗ) { if (݅1) { // ඳըͷͨΊͷॲཧ } else { // ඳըͷͨΊͷॲཧ } } else { // ඳըͷͨΊͷॲཧ } // ඳըͷͨΊͷॲཧ case .unknown: return cell } // ඳըͷͨΊͷॲཧ return cell } 15
TIMELINE ’S VIEWCONTROLLER REFACTORING func displayShiharaiItem(item: ShiharaiItem, indexPath: IndexPath) ->
TimelineTableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier, for: indexPath) as! TimelineTableViewCell let name: String guard let date = item.createdAt else { return cell } switch item.status { case .accepted: if (ࢧ͍͕ࣗ) { // ඳըͷͨΊͷॲཧ } else { // ඳըͷͨΊͷॲཧ } cell.mainLabel.attributedText = … case .rejected: if (ࢧ͍͕ࣗ) { if item.merchant == nil{ // ඳըͷͨΊͷॲཧ } else { // ඳըͷͨΊͷॲཧ } } else { // ඳըͷͨΊͷॲཧ } // ඳըͷͨΊͷॲཧ case .requested: if (ࢧ͍͕ࣗ) { if (݅1) { // ඳըͷͨΊͷॲཧ } else { // ඳըͷͨΊͷॲཧ } } else { // ඳըͷͨΊͷॲཧ } // ඳըͷͨΊͷॲཧ case .unknown: return cell } // ඳըͷͨΊͷॲཧ return cell } ViewControllerͳͷʹෳࡶͳذΛ͍ͯ͠Δ 16
TIMELINE ’S VIEWCONTROLLER REFACTORING ▸ ViewControllerͷ͋Δ1ͭͷϝιουͰλΠϜϥΠϯCellͷ ذͱඳը͢ΔใΛ٧ΊࠐΜͰ͍ͨ ղܾํ๏ ▸
ViewControllerͰPresenter͔ΒݴΘΕͨඳըʹઐ೦ ▸ λΠϜϥΠϯCellͷذϩδοΫ͚ͩͷϝιουΛPresenter ʹੜ͢ ▸ ͜ͷλΠϓͷCell͜ΕΛඳը͢Δɺͱ͍͏ϝιουΛੜ ͢(͜͜ͰCellʹੜͨ͠) 17
TIMELINE ’S VIEWCONTROLLER REFACTORING // ViewController override func tableView(_ tableView:
UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let item = getTimelineItem(indexPath: indexPath) else { return UITableViewCell() } guard let cellInfo = getTimelineCellInfo(indexPath: indexPath) else { return UITableViewCell() } return getCell(tableView, indexPath: indexPath, item: item, cellInfo: cellInfo) } // Presenter func getTimelineCellInfo(_ item: TimelineItem) -> TimelineCellInfo? { switch item { case let (ٻobject) as (ٻobject): switch (ٻobject).status { case .accepted: return TimelineCellInfo(type: .accepted(ٻobject)) case .requested: return TimelineCellInfo(type: .requested(ٻobject)) case .rejected: return TimelineCellInfo(type: .rejected(ٻobject)) default: return nil } case let (ࢧ͍object) as (ࢧ͍object): if (݅1) { switch (ࢧ͍object).status { case .accepted: return TimelineCellInfo(type: .accepted(ࢧ͍object)) case .requested: return TimelineCellInfo(type: .requested(ࢧ͍object)) case .rejected: return TimelineCellInfo(type: .rejected(ࢧ͍object)) default: return nil } } else if (݅2) { guard let subject = .. else { return nil } guard let secondarySubject = .. else { return nil } return TimelineCellInfo(type: .(ࢧ͍objectλΠϓ1), subject: subject, secondarySubject: secondarySubject) } else { if (݅a) { if let subject = .., let secondarySubject = .. { return TimelineCellInfo(type: .(ࢧ͍objectλΠϓ1), subject: subject, secondarySubject: secondarySubject) } } else if (݅b) { if let .. { return TimelineCellInfo(type: .(ࢧ͍objectλΠϓ2), subject: subject) } } else if (݅c) { if let .. { return TimelineCellInfo(type: .(ࢧ͍objectλΠϓ2), subject: subject) } } } case _ as ..: return TimelineCellInfo(type: .fuga) VC Presenter 18
TIMELINE ’S VIEWCONTROLLER REFACTORING // ViewController override func tableView(_ tableView:
UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let item = getTimelineItem(indexPath: indexPath) else { return UITableViewCell() } guard let cellInfo = getTimelineCellInfo(indexPath: indexPath) else { return UITableViewCell() } return getCell(tableView, indexPath: indexPath, item: item, cellInfo: cellInfo) } // Presenter func getTimelineCellInfo(_ item: TimelineItem) -> TimelineCellInfo? { switch item { case let (ٻobject) as (ٻobject): switch (ٻobject).status { case .accepted: return TimelineCellInfo(type: .accepted(ٻobject)) case .requested: return TimelineCellInfo(type: .requested(ٻobject)) case .rejected: return TimelineCellInfo(type: .rejected(ٻobject)) default: return nil } case let (ࢧ͍object) as (ࢧ͍object): if (݅1) { switch (ࢧ͍object).status { case .accepted: return TimelineCellInfo(type: .accepted(ࢧ͍object)) case .requested: return TimelineCellInfo(type: .requested(ࢧ͍object)) case .rejected: return TimelineCellInfo(type: .rejected(ࢧ͍object)) default: return nil } } else if (݅2) { guard let subject = .. else { return nil } guard let secondarySubject = .. else { return nil } return TimelineCellInfo(type: .(ࢧ͍objectλΠϓ1), subject: subject, secondarySubject: secondarySubject) } else { if (݅a) { if let subject = .., let secondarySubject = .. { return TimelineCellInfo(type: .(ࢧ͍objectλΠϓ1), subject: subject, secondarySubject: secondarySubject) } } else if (݅b) { if let .. { return TimelineCellInfo(type: .(ࢧ͍objectλΠϓ2), subject: subject) } } else if (݅c) { if let .. { return TimelineCellInfo(type: .(ࢧ͍objectλΠϓ2), subject: subject) } } } case _ as ..: return TimelineCellInfo(type: .fuga) VC Presenter ViewController΄ͱΜͲԿ͠ͳ͍ PresenterʹUIϩδοΫΛ·ͱΊͨͷͰςετॻ͖͍͢ 19
CONCLUSION ·ͱΊ ▸ ߏΫϦʔϯΞʔΩςΫνϟ͕ͩɺΛΓ͚Δաఔ Ͱਖ਼͘͠ఆٛ͠ͳ͍ͱബͬΒ͍͕ੜ·Εͯ͠·͏ ▸ ViewController -> Presenter ->
UseCase ͱϩδοΫΛΓ ͚͍ͯͬͨ ▸ ͦ͏͢Δ͜ͱͰϢχοτςετ͕ॻ͔Ε͍ͯͬͨ 20