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

Clean Architecture 2

Clean Architecture 2

C114c127f13522da92cb03e5d14946ca?s=128

Takuma Shimizu

August 29, 2018
Tweet

Transcript

  1. None
  2. ΫϦʔϯΞʔΩςΫνϟ ࣮ફͷࣄ࢝Ί ٕज़ษڧձ

  3. ಡॻձͷ͓஌Βͤ

  4. ୊ࡐ ϩόʔτɾ$Ϛʔνϯ
 ʰ$MFBO"SDIJUFDUVSFɹ ୡਓʹֶͿιϑτ΢ΣΞ ͷߏ଄ͱઃܭʱ
 ʢ֯੐యɾߴ໦ਖ਼߂༁ʣ

  5. w ΫϦʔϯΞʔΩςΫνϟࣄ࢝Ί લճ  w ΫϦʔϯΞʔΩςΫνϟ࣮ફࣄ࢝Ί ࠓճ  w ΫϦʔϯΞʔΩςΫνϟ࣮ફ

    ࣍ճ  w ΫϦʔϯΞʔΩςΫνϟ࣮ફ ࣍ʑճ  w ΫϦʔϯΞʔΩςΫνϟ࣮ફ ࣍ʑʑճ  w ΫϦʔϯΞʔΩςΫνϟ࣮ફ ࣍ʑʑʑճ  w ΫϦʔϯΞʔΩςΫνϟ࣮ફ ࣍ʑʑʑʑճ   w ΫϦʔϯΞʔΩςΫνϟ࣮ફO  ࣍ʑ\ O  ^ճ  
  6. w ΫϦʔϯΞʔΩςΫνϟࣄ࢝Ί લճ  w ΫϦʔϯΞʔΩςΫνϟ࣮ફࣄ࢝Ί ࠓճ  w ΫϦʔϯΞʔΩςΫνϟ࣮ફ

    ࣍ճ
  7. w ΫϦʔϯΞʔΩςΫνϟࣄ࢝Ί લճ  w ίʔυ͕ొ৔͠ͳ͍ཧ࿦తͳ࿩୊ w ΫϦʔϯΞʔΩςΫνϟ࣮ફ ࣍ճ 

    w $PDPB 5PVDI ͷجຊతͳύλʔϯ .7$ Λ࢖࣮ͬͨ૷ํ๏ w ΫϦʔϯΞʔΩςΫνϟ࣮ફࣄ࢝Ί ࠓճ  w ؆୯ͳྫ΍ίʔυ͕ొ৔͢Δલճͷ࿩୊Λਂ۷Γ
  8. w ΫϦʔϯΞʔΩςΫνϟࣄ࢝Ί લճ  w ίʔυ͕ొ৔͠ͳ͍ཧ࿦తͳ࿩୊ w ΫϦʔϯΞʔΩςΫνϟ࣮ફ ࣍ճ 

    w $PDPB 5PVDI ͷجຊతͳύλʔϯ .7$ Λ࢖࣮ͬͨ૷ํ๏ w ίʔυϨϏϡʔձ   w 4USJDUMZ PSUSJDLZ $MFBO"SDIJUFDUVSF w 7*1&3 ؒʹ߹͑͹ʜ w ΫϦʔϯΞʔΩςΫνϟ࣮ફࣄ࢝Ί ࠓճ  w ؆୯ͳྫ΍ίʔυ͕ొ৔͢Δલճͷ࿩୊Λਂ۷Γ
  9. લճͷ࿩୊ w ΫϦʔϯΞʔΩςΫνϟͷ؊ w #VTJOFTT3VMFT w &OUJUZ  $SJUJDBM 

    w 6TF$BTF "QQMJDBUJPOTQFDJpD  w ґଘΛҰํ޲ʹอͭ
  10. ࠓճͷ࿩୊ w &OUJUZ $SJUJDBM  w 6TF$BTF "QQMJDBUJPOTQFDJpD  w

    ࣸਅͷ&YJG΍.FUBEBUBΛѻ͏ΞϓϦ w -FWFM ϨΠϠʔ ؒͷσʔλͷड͚౉͠ํ๏
  11. ໨ඪ ୲౰Ҋ݅ͷ &OUJUZͱ6TF$BTF Λ۠ผͰ͖Δؾ͕͢Δ

  12. γφϦΦ w ࣸਅͷϝλσʔλΛ͚ͩͻͨ͢Βྻڍ͢ΔΞϓϦͷ࡞੒ ґཔ w ࣸਅͷฒͼ͸ॱෆಉͰߏΘͳ͍ w ίʔυྫͷෳࡶ͞Λͳͨ͘͢Ίʹ ࣸਅࣗମ͸දࣔ͠ͳ͍

  13. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  14. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  15. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  16. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  17. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  18. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  19. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  20. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  21. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  22. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  23. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  24. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  25. &OUJUZ struct Metadata: Comparable { enum FlashMode { case none,

    normal, redEye } init(properties: [CFString : Any]) var localIdentifier: String { get } var iso: Float { get } var focalLength: Float { get } var exposureValue: Float { get } var lensAperture: Float { get } var exposureDuration: CMTime { get } var flashMode: FlashMode { get } ŋ ŋ ŋ }
  26. 6TF$BTF *' public protocol MetadataListInteractor { func browseMetadata() } public

    protocol MetadataListOutput : AnyObject { func didProvideMetadataToBrowse(_: [BrowsingMetadata]) } • MetadataListInteractor w "EBQUFS૚ͷ$POUSPMMFS͔Βར༻ • MetadataListOutput w "EBQUFS૚ͷ1SFTFOUFSͰ࣮૷ w 6TF$BTF *OUFSBDUPSͷ࣮૷ ͔Βར༻
  27. 6TF$BTF *NQ struct MetadataListUseCase: MetadataListInteractor { private let output: MetadataListOutput

    func browseMetadata() { let metadata = repository.fetchMetadata() let metadataToBrowse = metadata.map(BrowsingMetadata.init(_:)) output.didProvideMetadataToBrowse(metadataToBrowse) } }
  28. 6TF$BTF *NQ struct MetadataListUseCase: MetadataListInteractor { private let output: MetadataListOutput

    func browseMetadata() { let metadata = repository.fetchMetadata() let metadataToBrowse = metadata.map(BrowsingMetadata.init(_:)) output.didProvideMetadataToBrowse(metadataToBrowse) } }
  29. %BUB4USVDUVSF public struct BrowsingMetadata { public var localIdentifier: String {

    get } public var iso: Float { get } public var focalLength: Float? { get } public var exposureValue: Float { get } public var lensAperture: Float? { get } public var exposureDuration: CMTime { get } } extension BrowsingMetadata { private init(_ metadata: Metadata) }
  30. %BUB4USVDUVSF public struct BrowsingMetadata { public var localIdentifier: String {

    get } public var iso: Float { get } public var focalLength: Float? { get } public var exposureValue: Float { get } public var lensAperture: Float? { get } public var exposureDuration: CMTime { get } } extension BrowsingMetadata { private init(_ metadata: Metadata) }
  31. %BUB4USVDUVSF extension BrowsingMetadata { private init(_ metadata: Metadata) } w

    ϨϕϧؒΛ·͙ͨσʔλߏ଄ମͷड౉͠ w ԼҐϨϕϧ 6TF$BTF ্͕ҐϨϕϧͷ&OUJUZΛม׵ w .FNCFSXJTFJOJUJBMJ[FS *OUFSOBM  w ςετίʔυͷͨΊʹ࢒͓ͯ͘͠ w !UFTUBCMFJNQPSUͰར༻
  32. <&OUJUZ> .FUBEBUB <6TF$BTF> .FUBEBUB-JTU 6TF$BTF <*OQVU<I>> .FUBEBUB-JTU *OUFSBDUPS <0VUQVU<I>> .FUBEBUB-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  33. γφϦΦ w ΍ͬͺΓιʔτػೳͷ௥Ճґཔ w ࢦఆ͞ΕͨϝλσʔλͰฒͼସ͑ w ॳظදࣔ͸γφϦΦͷॱෆಉͰͷฒͼʹͳΔ

  34. <&OUJUZ> .FUBEBUB <6TF$BTF> 0SEFSFE-JTU 6TF$BTF <*OQVU<I>> 0SEFSFE-JTU *OUFSBDUPS <0VUQVU<I>> 0SEFSFE-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6* .FUBEBUB-JTU 6$ *0
  35. <&OUJUZ> .FUBEBUB <6TF$BTF> 0SEFSFE-JTU 6TF$BTF <*OQVU<I>> 0SEFSFE-JTU *OUFSBDUPS <0VUQVU<I>> 0SEFSFE-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6* .FUBEBUB-JTU 6$ *0
  36. <&OUJUZ> .FUBEBUB <6TF$BTF> 0SEFSFE-JTU 6TF$BTF <*OQVU<I>> 0SEFSFE-JTU *OUFSBDUPS <0VUQVU<I>> 0SEFSFE-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  37. <&OUJUZ> .FUBEBUB <6TF$BTF> 0SEFSFE-JTU 6TF$BTF <*OQVU<I>> 0SEFSFE-JTU *OUFSBDUPS <0VUQVU<I>> 0SEFSFE-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  38. <&OUJUZ> .FUBEBUB <6TF$BTF> 0SEFSFE-JTU 6TF$BTF <*OQVU<I>> 0SEFSFE-JTU *OUFSBDUPS <0VUQVU<I>> 0SEFSFE-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6*
  39. มߋͳ͠ w ػೳͷมߋͰ͸ͳ͘ɺૢ࡞ํ๏ͷมߋ w ૢ࡞ํ๏ͷมߋͷӨڹ͸6TF$BTF΄Ͳड͚ʹ͍͘ &OUJUZ

  40. 6TF$BTF ௥Ճ public protocol OrderedMetadataListInteractor { func browseSortKeys() func browseOrderedMetadata(by

    key: MetadataListSortKey) } public protocol OrderedMetadataListOutput : AnyObject { func didProvideSortKeys(_: [MetadataListSortKey]) func didProvideSortedMetadataToBrowse(_: [BrowsingMetadata]) } public enum MetadataListSortKey { case iso, focalLength, exposureValue case lensAperture, exposureDuration } internal extension MetadataListSortKey : CaseIterable { }
  41. 6TF$BTF ௥Ճ internal extension MetadataListSortKey : CaseIterable { } public

    protocol OrderedMetadataListInteractor { func browseSortKeys() } public protocol OrderedMetadataListOutput : AnyObject { func didProvideSortKeys(_: [MetadataListSortKey]) }
  42. 6TF$BTF ௥Ճ public enum MetadataListSortKey { case iso, focalLength, exposureValue

    case lensAperture, exposureDuration } public protocol OrderedMetadataListInteractor { func browseOrderedMetadata(by key: MetadataListSortKey) } public protocol OrderedMetadataListOutput : AnyObject { func didProvideSortedMetadataToBrowse(_: [BrowsingMetadata]) }
  43. "EBQUFSͰ͸ • MetadataListInteractor ͱ OrderedMetadataListInteractor w ಉҰͷ$POUSPMMFS͔Βར༻ w $POUSPMMFS͕ͭͷ*OUFSBDUPSΛ࣋ͬͨঢ়ଶ •

    MetadataListOutput ͱ OrderedMetadataListOutput w ಉҰͷ1SFTFOUFSͰ࣮૷ w 1SFTFOUFS͕ͭͷ0VUQVUʹ४ڌͨ͠ঢ়ଶ
  44. "EBQUFSͰ͸ w $POUSPMMFS͕ͭͷ*OUFSBDUPSΛ࣋ͬͨঢ়ଶ w 1SFTFOUFS͕ͭͷ0VUQVUʹ४ڌͨ͠ঢ়ଶ w 6TF$BTF಺Ͱ΋มߋස౓͕ҟͳΔ΋ͷ͸෼཭ w ࠓճͷྫͰ͸ඍົ͔΋

  45. <&OUJUZ> .FUBEBUB <6TF$BTF> 0SEFSFE-JTU 6TF$BTF <*OQVU<I>> 0SEFSFE-JTU *OUFSBDUPS <0VUQVU<I>> 0SEFSFE-JTU

    0VUQVU <%BUB4USVDU> #SPXTJOH .FUBEBUB 6* .FUBEBUB-JTU 6$ *0
  46. γφϦΦ w ϝλσʔλΛվ͟ΜͰ͖Δػೳͷ௥Ճґཔ w ಛఆͷϝλσʔλ͚͕ͩฤूՄೳ w ݩͷࣸਅͱஔ͖׵͑ͯอଘ

  47. <&OUJUZ> .FUBEBUB <6TF$BTF> .PEJpDBUJPO 6TF$BTF <*OQVU<I>> .PEJpDBUJPO *OUFSBDUPS <0VUQVU<I>> .PEJpDBUJPO

    0VUQVU <%BUB4USVDU> .PEJGZJOH .FUBEBUB 6* .FUBEBUB-JTU 6$ *0 0SEFSFE-JTU 6$ *0
  48. <&OUJUZ> .FUBEBUB <6TF$BTF> .PEJpDBUJPO 6TF$BTF <*OQVU<I>> .PEJpDBUJPO *OUFSBDUPS <0VUQVU<I>> .PEJpDBUJPO

    0VUQVU <%BUB4USVDU> .PEJGZJOH .FUBEBUB 6* .FUBEBUB-JTU 6$ *0 0SEFSFE-JTU 6$ *0
  49. <&OUJUZ> .FUBEBUB <6TF$BTF> .PEJpDBUJPO 6TF$BTF <*OQVU<I>> .PEJpDBUJPO *OUFSBDUPS <0VUQVU<I>> .PEJpDBUJPO

    0VUQVU <%BUB4USVDU> .PEJGZJOH .FUBEBUB 6*
  50. <&OUJUZ> .FUBEBUB <6TF$BTF> .PEJpDBUJPO 6TF$BTF <*OQVU<I>> .PEJpDBUJPO *OUFSBDUPS <0VUQVU<I>> .PEJpDBUJPO

    0VUQVU <%BUB4USVDU> .PEJGZJOH .FUBEBUB 6*
  51. <&OUJUZ> .FUBEBUB <6TF$BTF> .PEJpDBUJPO 6TF$BTF <*OQVU<I>> .PEJpDBUJPO *OUFSBDUPS <0VUQVU<I>> .PEJpDBUJPO

    0VUQVU <%BUB4USVDU> .PEJGZJOH .FUBEBUB 6*
  52. &OUJUZ extension Metadata { func validate() -> Bool } w

    ػೳͷ௥Ճ͸ɺ&OUJUZʹ΋Өڹ͕ͰΔ w ػೳͷมߋ΋ಉ༷
  53. 6TF$BTF *' public struct ModifyingMetadata { public var localIdentifier: String

    { get } public var exposureValue: Float { get set } public var exposureDuration: CMTime { get set } } extension ModifyingMetadata { internal init(_ source: Metadata) } public protocol MetadataModificationInteractor { func requestToModifyMetadata(ofIdentifier localID: String) func modify(with modifyingMetadata: ModifyingMetadata) } public protocol MetadataModificationOutput : AnyObject { func didProvideMetadataToModify(_: inout ModifyingMetadata) func didModifyMetadata(_: ModifyingMetadata) func didFailToModifyMetadata(_: ModifyingMetadata) }
  54. 6TF$BTF *NQ struct MetadataModificationUseCase: MetadataModificationInteractor { private let output: MetadataModificationOutput

    func requestToModifyMetadata(ofIdentifier localID: String) { let source = repository.fetchMetadata( ofIdentifier: localID ) var metadataToModify = ModifyingMetadata(source) output.didProvideMetadataToModify(&metadataToModify) } }
  55. 6TF$BTF *NQ struct MetadataModificationUseCase: MetadataModificationInteractor { func modify(with modifyingMetadata: ModifyingMetadata)

    { let source = repository.fetchMetadata( ofIdentifier: modifyingMetadata.localIdentifier ) source.exposureValue = modifyingMetadata.exposureValue source.exposureDuration = modifyingMetadata.exposureDuration guard source.valiate() else { output.didFailToModifyMetadata(modifyingMetadata) return } repository.updatePhoto(with: source) output.didModifyMetadata(modifyingMetadata) } }
  56. %BUB4USVDUVSF public struct ModifyingMetadata { public var localIdentifier: String {

    get } public var exposureValue: Float { get set } public var exposureDuration: CMTime { get set } }
  57. %BUB4USVDUVSF public struct ModifyingMetadata { public var localIdentifier: String {

    get } public var exposureValue: Float { get set } public var exposureDuration: CMTime { get set } }
  58. %BUB4USVDUVSF w 6TF$BTF಺Ͱ΋มߋස౓͕ҟͳΔ΋ͷ͸෼཭ w ͦͷ෼཭ʹଇͬͯσʔλߏ଄ମ΋෼཭ w ઈରͰ͸ͳ͍ɻ΍Γ͗͢஫ҙ w ͲΜͳʹ෼཭ͯ͠΋
 6TF$BTFಉ࢜ͷׯব͕ආ͚ΒΕͳ͍৔߹΋͋Δ

    w σʔλߏ଄ମΛڞ༗͍ͯ͠Δ6TF$BTF΋ҶͮΔࣜʹมߋ
  59. <&OUJUZ> .FUBEBUB <6TF$BTF> .PEJpDBUJPO 6TF$BTF <*OQVU<I>> .PEJpDBUJPO *OUFSBDUPS <0VUQVU<I>> .PEJpDBUJPO

    0VUQVU <%BUB4USVDU> .PEJGZJOH .FUBEBUB 6* .FUBEBUB-JTU 6$ *0 0SEFSFE-JTU 6$ *0
  60. γφϦΦͷ·ͱΊ w ૢ࡞खॱͷ௥Ճɾมߋ͸ɺ6TF$BTFͷ௥ՃɾมߋͰରԠ w ػೳͷ௥Ճɾมߋ͸ɺ&OUJUZͱ6TF$BTFͷ௥ՃɾมߋͰରԠ w ʮͱΓ͋͑ͣ࡞ͬͯɺ͋ͱ͔ΒΞοϓσʔτʯʹϚον㾗 w ϨϕϧؒͰड͚౉͞ΕΔσʔλߏ଄ମ͸ɺ4XJGUͷTUSVDU͕ศར

  61. ͦͷଞͷ &OUJUZͱ6TF$BTF

  62. "MFSU$POUSPMMFS J04 w 1SFTFOUFSͰ"MFSU$POUSPMMFSΛੜ੒͢Δ৔߹ w 7JFXͰ"MFSU$POUSPMMFSΛੜ੒ɾදࣔ͢Δ৔߹

  63. "MFSU$POUSPMMFS J04 w 1SFTFOUFSͰ"MFSU$POUSPMMFSΛੜ੒͢Δ৔߹ protocol UserInformationUpdateOutput: AnyObject { func didFailToUpdateUserInformation(

    with error: Error, retrying: @escaping (Bool) -> Void ) } final class UserInformationPresenter: UserInformationUpdateOutput { func didFailToUpdateUserInformation( with error: Error, retrying: @escaping (Bool) -> Void) { let alert = // ... let retryAction = UIAlertAction(title: "Retry", style: .default) { _ in retrying(true) } alert.addAction(retryAction) let cancelAction = UIAlertAction(title: "Close", style: .cancel) { _ in retrying(false) } alert.addAction(cancelAction) view.show(alert) } }
  64. "MFSU$POUSPMMFS J04 w 1SFTFOUFSͰ"MFSU$POUSPMMFSΛੜ੒͢Δ৔߹ final class UserInformationUpdateUseCase: UserInfoUpdateInteractor { let

    output: UserInformationUpdateOutput func update(_ user: UserInformationUpdateOutput) { // ... let error = // ... output.didFailToUpdateUserInformation(with: error) { [weak self] isRetried in if isRetried { self?.update(user) } } } }
  65. "MFSU$POUSPMMFS J04 w 7JFXͰ"MFSU$POUSPMMFSΛੜ੒ɾදࣔ͢Δ৔߹ final class UserInformationPresenter: UserInfoUpdateOutput { let

    view: UserInformationView func didFailToUpdateUserInformation(with error: Error) { view.showError(withMessage: error.localizedDescription) } } final class UserInformationVC: UIVC, UserInfoView { func showError(withMessage message: String) { let alert = // ... let retry = UIAlertAction(title: "Retry", style: .default) { _ in controller.retry() } alert.addAction(retry) // ... present(alert, animated: true) } }
  66. "MFSU$POUSPMMFS J04 w 7JFXͰ"MFSU$POUSPMMFSΛੜ੒ɾදࣔ͢Δ৔߹ final class UserInformationUpdateUseCase: UserInfoUpdateInteractor { let

    output: UserInformationUpdateOutput func update(_ user: UserInformationUpdateOutput) { // ... let error = // ... output.didFailToUpdateUserInformation(with: error) } }
  67. "MFSU$POUSPMMFS J04 w 1SFTFOUFSͰ"MFSU$POUSPMMFSΛੜ੒͢Δ৔߹ w 7JFXͰ"MFSU$POUSPMMFSΛੜ੒ɾදࣔ͢Δ৔߹ w 6TF$BTF͕6*૚ͷӨڹΛड͚ͯ͠·͍ͬͯΔ w ํ਑ΛܾΊͯͲͷํ๏Ͱ࣮ݱ͢Δ͔Λ౷Ұ

    w ଥڠϙΠϯτ
  68. όϦσʔγϣϯ w &OUJUZͱ6TF$BTFͷͲͪΒͰόϦσʔτΛ͢΂͖͔ ˠͲͪΒ΋ߦ͏Մೳੑ͕͋Δ
 ྫɿೖྗϑΥʔϜ͔Βͷೖྗ஋Ͱϝλσʔλͷ஋Λߋ৽

  69. όϦσʔγϣϯ w ਺஋Λظ଴͢ΔϑΥʔϜͷೖྗ஋ 4USJOH ͷݕূ ˠ6TF$BTF͕୲౰͢Δ w &OUJUZΑΓ΋ೖྗʹ͍ۙ ԼҐϨϕϧ 

    w ͲΜͳૢ࡞ํ๏Ͱೖྗ͞ΕΔͷ͔͸γεςϜͷཁ݅
  70. όϦσʔγϣϯ w ೖྗ஋ ਺஋ ͰϝλσʔλΛߋ৽͢Δࡍͷଥ౰ੑ ˠ&OUJUZ͕୲౰͢Δ w ϝλσʔλͷ஋ͷ༗ޮൣғ͸γεςϜ͔Βಠཱͨ͠ఆٛ w &OUJUZ͸ࣗ਎ͷ੔߹ੑΛ୲อ

    %%%తͳࢹ఺
  71. l-FWFMzͰ͓͞Β͍ w Ϣʔβʔ΍γεςϜͷೖྗͱग़ྗ͔Β཭Ε͍ͯΔ΄Ͳ
 Ϩϕϧ͕ߴ͍ w όϦσʔγϣϯͷྫ w Ϩϕϧ͕ҟͳΕ͹มߋස౓ɾཧ༝΋ҟͳΔ w ϝλσʔλӾཡɾฤूͷྫ


    w ΑΓ-FWFM͕ߴ͍΄͏Λ&OUJUZʹ෼཭
  72. ໨ඪ ୲౰Ҋ݅ͷ &OUJUZͱ6TF$BTF Λ۠ผͰ͖Δؾ͕͢Δ

  73. *0ͷڑ཭ͱϨϕϧ ೖग़ྗͷڑ཭ͰϨϕϧΛ෼͚Δཧ༝ w ೖग़ྗͷํ๏͸6*ͷઃܭ΍ɺࣄۀઓུͳͲͷཧ༝͞ΕΔ w ೖग़ྗ͸ɺ֎తͳཁҼͷӨڹΛड͚΍͍͢
 ˠߋ৽ස౓͕ߴ͍ w ೖग़ྗͷ͔Βڑ཭ΛऔΓɺ֎తཁҼͷӨڹൣғΛڱΊΔ w

    ϨϕϧʹΑΔ໌ࣔతͳ۠ผ
  74. ೖग़ྗͱ௚઀ؔ܎͢Δ΋ͷͱɺͦ͏Ͱͳ͍΋ͷΛ෼͚Δ ௚઀ؔ܎͠ͳ͍΋ͷ͔Β6TF$BTFͱ&OUJUZΛݟ͚ͭΔ

  75. ໨ඪ ୲౰Ҋ݅ͷ &OUJUZͱ6TF$BTF Λ۠ผͰ͖Δؾ͕͢Δ

  76. ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠