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

ペイモのアーキテクチャ

 ペイモのアーキテクチャ

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

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