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

Clean Architecture with Vue

Clean Architecture with Vue

Attempting Clean Architecture with Vue.js and Vuex.

Event Link: https://kfug.connpass.com/event/90962/
GitHub Link: https://github.com/andoshin11/clean-architecture-example-vue

andoshin11

June 30, 2018
Tweet

More Decks by andoshin11

Other Decks in Technology

Transcript

  1. Clean Architecture with Vue
    Vue.js / Nuxt.js Meetup Osaka #0
    by andoshin11
    Attempting

    View Slide

  2. Who am I ?
    ● Andy (@andoshin11)
    ● Vue.js Japan User Group
    ● Frontend Developer @FOLIO
    ● JS, Ruby, Go, Perl, Python, PHP, Rust(?)

    View Slide

  3. View Slide

  4. Vue Fesやります!!

    View Slide

  5. 本日のゴール
    ● Clean Architectureの概要を理解する
    ● 「VueにClean Architectureを導入すべきか」を判断できるようになる

    View Slide

  6. View Slide

  7. Clean Architectureの基本
    ・オニオン型のレイヤードアーキテクチャ
    ・各レイヤーの名前は重要ではない
    ・依存性の矢印が単方向であることが大切
    ・内側のレイヤーは外の世界を知らない

    View Slide

  8. Clean Architectureの特徴
    ● ビジネスロジックがFWやUI、DB、外部API等に依存しない(Testable)
    ● ビジネスロジックはEntitiesとUsecasesに集約される
    ● 外界(UI等)からのデータの読み書きはInterface Adapter(Presenter, Controller)
    を通して行われる

    View Slide

  9. アプリケーション実装パターンのおさらい
    ● MVC
    ● MVVM
    ● DDD
    ● Flux

    View Slide

  10. MVC(割愛)
    ・Model - View - Controller
    ・Railsが採用しているやつ
    ・ViewがModelをObserve
    ・Fat Model, Fat Controller問題
    ・「データの振舞い」を定義する余地がない

    View Slide

  11. MVVM(割愛)
    ・Vue Componentがやってるやつ
    ・Modelは生データおよびDomain Model
    ・ファサードとしてのVM
    ・ViewとVMにおいてデータバインディングが成立しているので
    Presenterやイベントを受け
    取るControllerが不要

    View Slide

  12. DDD(レイヤードアーキテクチャ)
    ・業務上の関心事(ドメイン)を中心に据えた
    設計手法
    ・Domain Layerでデータの振舞を定義
    ・責務が分離されているため、フレームワー
    クやライブラリに依存しづらい
    ・レイヤー間の依存性は単方向でない

    View Slide

  13. Flux
    ・Facebook社が提唱
    ・Redux, Vuex等
    ・CQRS
    ・Event Sourcing
    ・単方向データフロー

    View Slide

  14. Flux はClean Architectureに近い?

    View Slide

  15. DDDの観点から見るFlux(Vuex)
    ● UIコンポーネント - Presentation層にあたる。イベントの発火も。
    ● Action - Application層。API通信だけでなくデータ処理に必要な手続き全般を担うた
    めDomain層も兼ねることが多い。
    ● Mutation - StoreのInput Port。ロジックは持たない。
    ● Store - オンメモリでデータを永続化。外部への柔軟な
    Output Portを持つ。

    View Slide

  16. Vuexを利用したFluxパターン(課題)
    ● Actionsにアプリケーションロジックが集約しがち。
    ● ドメインモデル(振舞いを持ったデータモデル)ってどこに書くんだっけ?
    ● Storeの構造がViewを意識したものになりがち
    ● Gettersを全てのViewに用意するのは厳しい
    ● Mutation(≒ Store)にロジックを書く人間が後を断たない
    (書けてしまうので)
    ● 本当にTestable?

    View Slide

  17. スケールしなさそう・・・

    View Slide

  18. 今回の設計方針
    ・より厳密なレイヤー分割を行う
    ・業務上の関心と技術上の関心を分離 → Domain Modelの活用(DDD Like)
    ・シンプルなイベント伝達 → 単方向データフロー(Flux Like)
    ・依存性も単方向にしてよりテスタブルに → Clean Architecture
    ・フレームワークや外部のI/Fに依存しない → Gatewayの活用

    View Slide

  19. スケールさせるぞ!!

    View Slide

  20. Container
    Controller
    Use Case
    Repository
    Store
    Entity
    Presenter
    UI Components
    Query
    Command

    View Slide

  21. アプローチ
    ● Controllerからイベントを発火
    ● Usecaseにビジネスロジックを記述。DI(依存性の注入)はControllerで
    ● データモデルの振舞いを定義する
    Entity層を用意
    ● Repository内でStoreにアクセス
    ● UIはPresenterで抽出したデータセットの写像である

    View Slide

  22. 実装編
    https://github.com/andoshin11/clean-architecture-example-vue

    View Slide

  23. 登場人物
    今回はNuxtつかってません!! (土下座)

    View Slide

  24. Store
    ● DomainごとにModule化
    ● Actionsは持たない
    ● Observableな箱としての用途
    ● 無理やり型付けしてます

    View Slide

  25. Entity
    ● Interfaceの提供
    ● Domainロジックの定義
    ● Data Store Layerへの読み書きを許
    容(through Vuex API)

    View Slide

  26. Repository
    ● アプリケーション固有のDomainロ
    ジックを定義
    ● Data Store Layerへアクセスを持つ
    (through Vuex API)

    View Slide

  27. Container
    ● UIの表示単位
    ● Atomic DesignでいうPages?
    ● ContainerごとにUse Caseと
    Presenterを持つ
    ● Containerを1つのドメインとみなした
    DucksなStore実装も可能

    View Slide

  28. Use Case
    ● アプリケーションに必要な手続き
    を定義
    ● DIされてはじめて動く

    View Slide

  29. Presenter
    ● 表示要件に必要なデータを
    Storeから抽出・整形
    ● 純粋関数として定義し、
    Computed プロパティにマッピ
    ング

    View Slide

  30. Container View
    ● Presenterの値をUI Componentに注入
    ● Use Caseに依存性を注入する(Domain
    Injection)
    ● 現状Controllerも含まれてしまっている

    View Slide

  31. Container
    Controller
    Use Case
    Repository
    Store
    Entity
    Presenter
    UI Components
    Query
    Command

    View Slide

  32. Testing
    ● UIコンポーネント - Presenterの写像なので再現が簡単
    ● Repositories - Data Store LayerへのRead & Write APIをテスト
    ● Use Cases - Given ConditionとしてRepositoryとServiceのモックをDIするだけ
    ● Entities- Use Casesと同様

    View Slide

  33. まとめ:
    ● いたずらにレイヤーを増やせば良いというわけではない
    ● 依存の方向性を意識することで変更に強いアプリケーションに近づく
    ● Vuexと周辺のテストツールを信用しきるならデフォルトの
    API叩く方が楽(今は
    Gatewayを使っていない)
    ● Clean Architectureの導入コストは高いので見極めが大事

    View Slide

  34. これってVueじゃなくてもできるのでは?

    View Slide

  35. We Are Hiring!!

    View Slide

  36. 参考:
    ● https://qiita.com/kondei/items/41c28674c1bfd4156186
    ● https://speakerdeck.com/takasek/10fen-tezhen-rifan-rusohutoueaakitekutiyafalseli-shi-2017
    ● http://embryo.hatenadiary.com/entry/2016/12/16/011446
    ● https://github.com/azu/large-scale-javascript
    ● https://qiita.com/[email protected]/items/705360b357c2a00c9532

    View Slide