Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ペイモのアーキテクチャ

 ペイモのアーキテクチャ

割り勘アプリのアーキテクチャについての発表です。

91d36c66b64ce58f3e749d9d921aae69?s=128

Shuichi Nagao

February 19, 2018
Tweet

Transcript

  1. ϖΠϞͷΞʔΩςΫνϟ @NGO275 1

  2. AGENDA ࠓ೔࿩͢͜ͱ ▸ ΫϦʔϯΞʔΩςΫνϟͱ͸ ▸ ϖΠϞͷΞʔΩςΫνϟ֓؍ ▸ ϖΠϞͷ࣮ࡍͷϦϑΝΫλྫ ▸ ·ͱΊ

    2
  3. WHAT IS CLEAN ARCHITECTURE? ΫϦʔϯΞʔΩςΫνϟͱ͸ 3

  4. WHAT IS CLEAN ARCHITECTURE? ΞϓϦ։ൃ͋Δ͋Δ ▸ ϏδωεϩδοΫ͕ͩΜͩΜΘ͔Βͳ͘ͳΔ ▸ ೖग़ྗͷॲཧ͕ࢄࡒͯ͠ॲཧΛ௥͏ͷ͕େมʹͳΔ ▸

    ঢ়ଶΛ࣋ͭ΋ͷ͕૿Ճͯ͠෭࡞༻Λଟ͘ੜΜͰ͠·͏ 4
  5. WHAT IS CLEAN ARCHITECTURE? ղܾ͍ͨ͜͠ͱ ▸ ϏδωεϩδοΫΛ໌֬ʹ͍ͨ͠ ▸ ϑϨʔϜϫʔΫ͔Βಠཱ͢Δ ▸

    ϏδωεϩδοΫ͸ετΞ͔Βಠཱ͢Δ ▸ ϏδωεϩδοΫ͸UI͔Βಠཱ͢Δ ▸ ϏδωεϩδοΫΛςετ͠΍͘͢Δ 5
  6. WHAT IS CLEAN ARCHITECTURE? ղܾํ๏ Πϝʔδਤ https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html 6

  7. PAYMO ARCHITECTURE ϖΠϞͷΞʔΩςΫνϟ֓؍ 7

  8. PAYMO ARCHITECTURE ϦϦʔε౰ॳͷϖΠϞͷΞʔΩςΫνϟΠϝʔδ ▸ View͕Ͱ͔͘ɺPresenterͱUseCase͸΄΅ۭͬΆ ▸ DataStore͕গʑେ͖͍ ▸ ϩδοΫ͕View΍DataStoreʹॻ͍ͯ͋ͬͨ ▸

    1݄ࠒ 8
  9. PAYMO ARCHITECTURE ϦϦʔε౰ॳͷϖΠϞͷΞʔΩςΫνϟΠϝʔδ ▸ View͕Ͱ͔͘ɺPresenterͱUseCase͸΄΅ۭͬΆ ▸ DataStore͕গʑେ͖͍ ▸ ϩδοΫ͕View΍DataStoreʹॻ͍ͯ͋ͬͨ ▸

    1݄ࠒ 9
  10. PAYMO ARCHITECTURE վળޙͷϖΠϞͷΞʔΩςΫνϟΠϝʔδᶃ ▸ PresenterʹUIϩδοΫҠߦ ▸ 7݄ࠒ 10

  11. PAYMO ARCHITECTURE վળޙͷϖΠϞͷΞʔΩςΫνϟΠϝʔδᶃ ▸ PresenterʹUIϩδοΫҠߦ ▸ 7݄ࠒ 11

  12. PAYMO ARCHITECTURE վળޙͷϖΠϞͷΞʔΩςΫνϟΠϝʔδᶄ ▸ ϏδωεϩδοΫΛUseCaseʹҠߦ ▸ 10݄ࠒ 12

  13. PAYMO ARCHITECTURE վળޙͷϖΠϞͷΞʔΩςΫνϟΠϝʔδᶄ ▸ ϏδωεϩδοΫΛUseCaseʹҠߦ ▸ 10݄ࠒ 13

  14. PAYMO REFACTORING ϖΠϞͷ࣮ࡍͷϦϑΝΫλྫ 14

  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 } 15
  16. 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
  17. TIMELINE ’S VIEWCONTROLLER REFACTORING ໰୊఺ ▸ ViewControllerͷ͋Δ1ͭͷϝιουͰλΠϜϥΠϯCellͷ ෼ذͱඳը͢Δ৘ใΛ٧ΊࠐΜͰ͍ͨ ղܾํ๏ ▸

    ViewControllerͰ͸Presenter͔ΒݴΘΕͨඳըʹઐ೦ ▸ λΠϜϥΠϯCellͷ෼ذϩδοΫ͚ͩͷϝιουΛPresenter ʹੜ΍͢ ▸ ͜ͷλΠϓͷCell͸͜ΕΛඳը͢Δɺͱ͍͏ϝιουΛੜ΍ ͢(͜͜Ͱ͸Cellʹੜ΍ͨ͠) 17
  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 18
  19. 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
  20. CONCLUSION ·ͱΊ ▸ ߏ଄͸ΫϦʔϯΞʔΩςΫνϟ͕ͩɺ੹຿Λ੾Γ෼͚Δաఔ Ͱਖ਼͘͠ఆٛ͠ͳ͍ͱബͬ΃Β͍૚͕ੜ·Εͯ͠·͏ ▸ ViewController -> Presenter ->

    UseCase ͱϩδοΫΛ੾Γ ෼͚͍ͯͬͨ ▸ ͦ͏͢Δ͜ͱͰϢχοτςετ͕ॻ͔Ε͍ͯͬͨ 20