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

ペイモのアーキテクチャ

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

 ペイモのアーキテクチャ

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

Avatar for Shuichi Nagao

Shuichi Nagao

February 19, 2018
Tweet

More Decks by Shuichi Nagao

Other Decks in Programming

Transcript

  1. WHAT IS CLEAN ARCHITECTURE? ղܾ͍ͨ͜͠ͱ ▸ ϏδωεϩδοΫΛ໌֬ʹ͍ͨ͠ ▸ ϑϨʔϜϫʔΫ͔Βಠཱ͢Δ ▸

    ϏδωεϩδοΫ͸ετΞ͔Βಠཱ͢Δ ▸ ϏδωεϩδοΫ͸UI͔Βಠཱ͢Δ ▸ ϏδωεϩδοΫΛςετ͠΍͘͢Δ 5
  2. 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
  3. 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
  4. TIMELINE ’S VIEWCONTROLLER REFACTORING ໰୊఺ ▸ ViewControllerͷ͋Δ1ͭͷϝιουͰλΠϜϥΠϯCellͷ ෼ذͱඳը͢Δ৘ใΛ٧ΊࠐΜͰ͍ͨ ղܾํ๏ ▸

    ViewControllerͰ͸Presenter͔ΒݴΘΕͨඳըʹઐ೦ ▸ λΠϜϥΠϯCellͷ෼ذϩδοΫ͚ͩͷϝιουΛPresenter ʹੜ΍͢ ▸ ͜ͷλΠϓͷCell͸͜ΕΛඳը͢Δɺͱ͍͏ϝιουΛੜ΍ ͢(͜͜Ͱ͸Cellʹੜ΍ͨ͠) 17
  5. 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
  6. 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