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

FiNCのクライアントアーキテクチャを揃える試み / 20190110 #app_mp

takasek
January 10, 2019

FiNCのクライアントアーキテクチャを揃える試み / 20190110 #app_mp

【増枠】App Client Melting Pot #1「設計」 - connpass
https://app-client-mp.connpass.com/event/112973/
での発表資料です。

# 参考リンク

PEAKS(ピークス)|関 義隆, 松館 大輝, 史 翔新, 田中 賢治, 鈴木 大貴, 杉上 洋平 - iOSの設計パターンを入門から徹底解説「iOSアプリ設計パターン入門」執筆プロジェクト!
https://peaks.cc/iOS_architecture

マイクロサービスとクライアント: 
理想と現実の狭間で / Ideal and Reality of microservices from the client-side - Speaker Deck
https://speakerdeck.com/qsona/ideal-and-reality-of-microservices-from-the-client-side

10分で振り返るソフトウェアアーキテクチャの歴史2017 - Speaker Deck
https://speakerdeck.com/takasek/10fen-tezhen-rifan-rusohutoueaakitekutiyafalseli-shi-2017

アプリのアーキテクチャ ガイド  |  Android Developers
https://developer.android.com/jetpack/docs/guide#addendum

conference-app-2018/Result.kt at master · DroidKaigi/conference-app-2018
https://github.com/DroidKaigi/conference-app-2018/blob/master/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/Result.kt

Result V.S. Result - Speaker Deck
https://speakerdeck.com/inamiy/result-v-dot-s-result-t-e

マイクロサービスとクライアントとコンテキスト境界 / 20181030 #microserv - Speaker Deck
https://speakerdeck.com/takasek/20181030-number-microserv

実践、BFF ~ BFFはFiNCのアプリで何を解決したのか ~ - Speaker Deck
https://speakerdeck.com/kensukeizumi/shi-jian-bff-bffhafincfalseapuridehe-wojie-jue-sitafalseka

takasek

January 10, 2019
Tweet

More Decks by takasek

Other Decks in Programming

Transcript

  1. FiNCͷ ΫϥΠΞϯτΞʔΩςΫνϟΛ ἧ͑ΔࢼΈ For App Client Melting Pot #1 2019/1/10

    FiNC Technologies Inc. / iOS Development Team ؔ ོٛ(takasek)
  2. !3 • ʮJ04ΞϓϦઃܭύλʔϯೖ໳ʯ ڞஶ  • 1&",4ΑΓɺۙ೔Ұൠൃച։࢝ʂ IUUQTQFBLTDDJ04@BSDIJUFDUVSF .7$ .71

    .77. 'MVY 3FEVY $MFBO"SDIJUFDUVSF  ϞόΠϧಛ༗ͷىಈܦ࿏ɾը໘ભҠͷ੔ཧ·Ͱ໢ཏʂ ؔ͸ɺʮઃܭͱ͸Կ͔ʯͱ͍͏େ͖ͳओޠͰষ΄Ͳʂ ೥ .7$ ʙ͔Β࿈໖ͱଓ͘ ΞʔΩςΫνϟύλʔϯͷྺ࢙ͷ੔ཧʂ ϚαΧϦඞࢸͷϏοάΠγϡʔʹՌ׶ʹ௅Έ·ͨ͠ʂ એ఻
  3. !5 FiNCͷ։ൃମ੍ɾαʔϏεߏ੒ • J04 "OESPJEฒߦ։ൃ • Ϣʔβʔछผɺϓϥϯ͕ଟ͍ • Ұൠɺ՝ۚɺ๏ਓͳͲ •

    Ωϟϯϖʔϯ΍Πϕϯτ΋ൃੜ • ͝΄͏ͼ΢ΥʔΧʔͳͲ Ϗδωε୯ҐͰνʔϜΛ૊Ή
  4. !15 Presentation Domain Separation • )VNBO*OUFSGBDF(VJEFMJOFTWT.BUFSJBM%FTJHO • QVTI NPEBMͰ؅ཧ͞ΕͨભҠߏ଄WTDPOUFYUͰ؅ཧ͞Εͨ"DUJWJUZ •

    6*5BCMF7JFXWT3FDZDMFS7JFX • FUD ϓϥοτϑΥʔϜʹΑͬͯઃܭࢥ૝ɾϑϨʔϜϫʔΫ͸େ͖͘ҟͳΔ ͔͠͠Model͸มΘΒͳ͍ ɹɹ˞ Model ͱ͸ʮσʔλߏ଄Λ͋ΒΘ͢ΦϒδΣΫτʯͰ͸ͳ͍ɻ ɹɹɹʮViewʹؔΘΒͳ͍஌ࣝʯ͢΂ͯͷ͜ͱɻ
  5. !18 MVVMͷݕ౼ • .PEFMͰ΋ඇಉظॲཧ͕ى͜Γ͏Δ͠ɺೖྗͱग़ྗͷؔ܎͸OOʹͳΔ • ίϚϯυΫΤϦ෼཭ݪଇʢ$24ʣ • ίϚϯυʢ෭࡞༻Λ൐͏ʣ͸౤͛Δ͚ͩ • ΫΤϦʢ෭࡞༻Λ൐Θͳ͍ʣ͸݁ՌΛड͚औΔ͚ͩ

    • .PEFM͔Βड͚औΔ݁Ռ΋0CTFSWBCMF ετϦʔϜ Ͱදݱ͍ͨ͠ AndroidͰ͸ɺLiveData͕͋Ε͹ผϥΠϒϥϦෆཁʁ NO! → ͲͪΒͷϓϥοτϑΥʔϜͰ΋ϦΞΫςΟϒϥΠϒϥϦ͕ཉ͍͠
  6. !27 Resource<T, E> ܕ • JO1SPHSFTT %PVCMF  • TVDDFTT

    5  • GBJMVSF & ඇಉظʹऔಘ͞ΕΔϦιʔεͷঢ়ଶΛɺ໢ཏੑΛ΋ͬͯදݱ͍ͨ͠ ໢ཏੑ͕͋Δ ʹ ύλʔϯϚονͰ͖Δ
  7. !28 Resource<T, E> ܕ ݩωλ(1): Android Jetpack
 https://developer.android.com/jetpack/docs/guide#addendum //a generic

    class that describes a data with a status public class Resource<T> { @NonNull public final Status status; @Nullable public final T data; @Nullable public final String message; private Resource(@NonNull Status status, @Nullable T data, @Nullable String message) { this.status = status; this.data = data; this.message = message; } public static <T> Resource<T> success(@NonNull T data) { return new Resource<>(SUCCESS, data, null); } public static <T> Resource<T> error(String msg, @Nullable T data) { return new Resource<>(ERROR, data, msg); } public static <T> Resource<T> loading(@Nullable T data) { return new Resource<>(LOADING, data, null); } }
  8. !29 Resource<T, E> ܕ ݩωλ(2): DroidKaigi/conference-app-2018
 https://github.com/DroidKaigi/conference-app-2018/blob/master/app/src/main/java/io/github/droidkaigi/confsched2018/presentation/Result.kt sealed class Result<T>(val

    inProgress: Boolean) { class InProgress<T> : Result<T>(true) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false return true } override fun hashCode(): Int = javaClass.hashCode() } data class Success<T>(var data: T) : Result<T>(false) data class Failure<T>(val errorMessage: String?, val e: Throwable) : Result<T>(false) companion object { fun <T> inProgress(): Result<T> = InProgress() fun <T> success(data: T): Result<T> = Success(data) fun <T> failure(errorMessage: String, e: Throwable): Result<T> = Failure(errorMessage, e) } } ύλʔϯϚον͠΍ͯ͘͢ྑ͍Ͷ
  9. !30 Resource<T> ͔ Resource<T, E> ͔ inamiyʮResult<T> V.S. Result<T, E>ʯ

    p7, 11 https://speakerdeck.com/inamiy/result-v-dot-s-result-t-e • ʮ͋Δ6TF$BTFͰى͜Γ͏ΔΤϥʔʯ
 ʮ͋Δ7JFX.PEFMͰى͜Γ͏ΔΤϥʔʯ͸ίϯςΩετ͕ҧ͏ • ໢ཏతʹදݱɾϋϯυϦϯά͍ͨ͜͠ͱ͕ଟ͍ • ʮΤϥʔʹͳΒͳ͍ʯ͜ͱ΋ࣔͤΔ
  10. !32 Resource × Rx Ͱ͞Βʹศརʹ extension Resource: ReactiveCompatible {} public

    enum ResourceTriggerSwitchingStrategy { case useFormer, useLatter } extension Reactive { public static func from<T, E: Error, Trigger: ObservableType>( trigger: Trigger, then execute: @escaping (Trigger.E) -> Single<T>, switchingStrategy: ResourceTriggerSwitchingStrategy ) -> Observable<Resource<T, E>> where Base == Resource<T, E> { let transform: (Trigger.E) -> Observable<Resource<T, E>> = { arg in return execute(arg) .asObservable() .map { .success($0) } .catchError { .just(.failure($0 as! E)) } .startWith(.inProgress(0)) } switch switchingStrategy { case .useFormer: return trigger.flatMapFirst(transform).share() case .useLatter: return trigger.flatMapLatest(transform).share() } } }
  11. !34 Q. ຊ౰ʹiOS/AndroidΛἧ͑ΒΕͨͷʁ • 4XJGUͱ,PUMJO͸΍ͬͺΓҧ͏ • 4XJGUͰ͸δΣωϦοΫͳJOUFSGBDF͕࢖͑ͳ͍ • FOVN͸TFBMFEDMBTTͱҧ͍ɺ֤έʔεΛܕϨϕϧͰ۠ผ͠ͳ͍ •

    QBDLBHFͷཻ౓͕ҧ͍ʢ,PUMJO͸σΟϨΫτϦ୯Ґʣɺ໋໊ʹӨڹ • 3Y4XJGUͱ3Y+BWB͸ҙ֎ͱҧ͏ • *0εϨουपΓɺ1SPDFTTPS 'MPXBCMF CBDLQSFTTVSF • ΠϯελϯεͷϥΠϑαΠΫϧ • TVCTDSJCF EJTQPTFͷڍಈ • ࢀরΧ΢ϯτWTΨϕʔδίϨΫγϣϯ • ΦϖϨʔλͷ໊લ΋ࢥͬͨΑΓଗͬͯͳ͍ • ࠩ෼ߋ৽Λલఏʹ͢Δ͔Ͳ͏͔Ͱߟ͑ํ͕มΘΔ • "OESPJEʹ͸4VQQPSU-JCSBSZͰ௥Ճ͞Εͨ%JGG6UJM͕͋Δ • J04͸σϑΝΫτελϯμʔυ͕ͳ͍ A. େମ͍͚Δ͚Ͳɺ೉͍͠෦෼͸͋Δ
  12. !35 Q. ΞϓϦશମΛἧ͖͑ͬͨͷʁ • طଘίʔυ·ͰҰؾʹ߹ΘͤΔ͜ͱ͸Ͱ͖ͳ͍ • ίʔυϕʔε͕ҧ͏ͷͰɺϦϑΝΫλͳͲΛ͖͔͚ͬʹࠩҟ͸ग़Δ • ઃܭ͸઴ਐతʹਐԽͤ͞Δ΂͖ •

    Կ͕ʮ࠷৽ͷਖ਼ղʯ͔ݟ͑ʹ͍͘ͱ͍͏໰୊ʹ޲͖߹͏ • υΩϡϝϯςʔγϣϯͰରԠ͠Α͏ͱ͢Δͱ
 ϓϩμΫτίʔυ͔Βဃ཭͠΍͍͢  • ϛχϚϜͳઃܭύλʔϯΛఏࣔͰ͖ΔΑ͏ɺ
 αϯϓϧϓϩδΣΫτΛ੔͑Δ A. ͖ͬͱӬԕʹWIP
  13. !36 Q. ΞʔΩςΫνϟΛἧ͑ͯྑ͔ͬͨ఺͸ʁ • 6*ʹҾ͖ͣΒΕͣʹ
 ʮυϝΠϯ͸Կ͔ʯΛத৺ͱͨٞ͠࿦͕͠΍͍͢ • ࢓༷ͷߟྀ࿙Εɾઃܭͷѱ͞ʹؾ෇͚Δ • ࣮࣭ϖΞϓϩ

    • ࡉ͔͍ઃܭʹࠩҟ͕ग़͏Δ໰୊ʹରͯ͠͸ɺ
 ׬શΛٻΊΔ΂͖Ͱ͸ͳ͍͕ɺ
 ίϯςΩετΛ҆ఆͤ͞Δ౒ྗ͸େ੾ A. ୈҰʹ͸ɺυϝΠϯ΁ͷҙ͕ࣝڧ·ͬͨ͜ͱ
  14. !39 Q. Kotlin/NativeͬͯͲ͏ͳͷʁ • 4XJGUඇαϙʔτ • ,PUMJO0CK$4XJGUͷม׵͸Ͱ͖Δ͚Ͳɺ
 ಛʹTUSVDU΍୅਺తσʔλܕ͕࢖͑ͳ͍ͷ͸ݫ͍͠ • .PEFM૚ͷόΠφϦαΠζ͕ංେԽ͢Δʢ༧ײʣ

    • 7JFX૚Ͱ3Y4XJGU .PEFM૚Ͱ3Y+BWBΛೖΕΔΈ͍ͨͳʜ • .PEFM૚΋ͳΔ΂͘ϓϨʔϯʹߏ੒͢Δ͜ͱΛҙࣝ • ,PUMJOɺ4XJGUͰɺͲͪΒͰ΋BTZODBXBJU͕
 ࢖͑ΔੈքʹͳͬͨΒݟ͑Δ΋ͷ͕มΘ͖ͬͯͦ͏ A. কདྷʹظ଴