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

ドメイン駆動設計を支えるアーキテクチャテスト / RAKUS Meetup Osaka 5

Yu Kawanami
February 05, 2020

ドメイン駆動設計を支えるアーキテクチャテスト / RAKUS Meetup Osaka 5

RAKUS Meetup Osaka #5「SaaSを支える開発原則」の登壇資料

https://rakus.connpass.com/event/161744/

※本資料は Object-Oriented Conference 2020 の登壇資料のベータ版です。
完成版はこちら
https://speakerdeck.com/kawanamiyuu/object-oriented-conference-2020

Yu Kawanami

February 05, 2020
Tweet

More Decks by Yu Kawanami

Other Decks in Technology

Transcript

  1. ドメイン駆動設計を支える
    アーキテクチャテスト
    RAKUS Meetup Osaka #5
    SaaS を支える開発原則
    @kawanamiyuu

    View full-size slide

  2. 2
    https://ooc.dev

    View full-size slide

  3. 3
    https://speakerdeck.com/kawanamiyuu/jjug-ccc-2019-spring

    View full-size slide

  4. 自己紹介
    ● かわなみゆう
    ● @kawanamiyuu
    ● 株式会社ラクス / Lead Engineer
    ● HR Tech x SaaS の開発
    ● Java (Spring Boot, Doma) / Vue.js / Puppeteer
    ● 自動テスト(が書きやすい設計を考えながらコード) を書くのがすき
    4

    View full-size slide

  5. Context Map
    5
    https://www.infoq.com/articles/ddd-contextmapping/

    View full-size slide

  6. Context Map
    6
    https://www.infoq.com/articles/ddd-contextmapping/

    View full-size slide

  7. Layer Architecture
    (〇〇〇〇を逆転したレイヤードアーキテクチャ) 7
    (一般的なレイヤードアーキテクチャ)

    View full-size slide

  8. Layer Architecture
    (〇〇〇〇を逆転したレイヤードアーキテクチャ) 8
    (一般的なレイヤードアーキテクチャ)

    View full-size slide

  9. Clean Architecture
    9

    View full-size slide

  10. Clean Architecture
    10

    View full-size slide

  11. Domain Model
    Employee
    Procedure
    Report
    xxx
    yyy
    11

    View full-size slide

  12. 依存関係
    12

    View full-size slide

  13. アーキテクチャとは
    「依存関係」のガイドライン
    13

    View full-size slide

  14. アーキテクチャの正体
    ● アーキテクチャとはソフトウェアの構造についての取り決めで
    あり、
    ● 解像度を上げていくと、ソフトウェアを構成する責務や関心事
    の「依存関係」についての取り決め
    14

    View full-size slide

  15. アーキテクチャの視座
    ● 責務や関心事の粒度
    ○ 大きな粒度:コンテキスト、レイヤー
    ○ 小さな粒度:パッケージ、クラス
    ● それぞれの粒度で依存関係を注意深く設計する
    15

    View full-size slide

  16. アーキテクチャとオブジェクト指向設計原則
    ● (乱暴に言うと)Layer Architecture も Clean Architecture
    も 、DDD のような設計論も、依存関係を適切に設計したいだ

    ● その土台としてのオブジェクト指向設計原則
    ○ 単一責任の原則(SRP)
    ○ 依存関係逆転の原則(DIP)
    16

    View full-size slide

  17. 「アーキテクチャ」の問題点
    17

    View full-size slide

  18. 「ガイドライン」というものの性質
    ● ガイドラインとは「指針」「ルール」「マナー」
    ● 人が決めて、守る(守らせる)
    ● 最初にルールをつくるのは、簡単
    ● ルール通りつくり始めるのも、簡単
    18

    View full-size slide

  19. 「ガイドライン」というものの性質
    ● ガイドラインとは「指針」「ルール」「マナー」
    ● 人が決めて、守る(守らせる)
    ● 最初にルールをつくるのは、簡単
    ● ルール通りつくり始めるのも、簡単
     なにが難しいのか?
    19

    View full-size slide

  20. アーキテクチャの品質維持は難しい
    人が決めたことであるがゆえに、壊れやすい。
    時間が経つと「大きな泥団子(Big Ball of Mud)」に。
    ● ありえる要因
    ○ 設計知識の属人化・暗黙知化
    ○ 開発スキルのばらつき
    ○ 納期優先、相次ぐメンバー増員
    20

    View full-size slide

  21. どうすればよいか?
    21

    View full-size slide

  22. 22
    アーキテクチャをテストしたい

    View full-size slide

  23. 23
    https://www.archunit.org/

    View full-size slide

  24. ArchUnit
    ● GitHub
    ○ https://github.com/TNG/ArchUnit
    ○ https://github.com/TNG/ArchUnit-Examples
    ● Twitter
    ○ https://twitter.com/archtests
    ● Technology Radar
    ○ https://www.thoughtworks.com/radar/tools/archunit
    ○ 進化的アーキテクチャ x 適応度関数
    24

    View full-size slide

  25. ArchUnit を一言でいうと
    ● Java(や Kotlin, Scala)で書かれたアプリケーションのパッ
    ケージやクラスの依存関係を JUnit のテストコードとして表現
    し、テストできるテストフレームワーク
    ● 依存関係の他にも、そのアプリケーション固有の実装ルール
    もテストすることができる
    25

    View full-size slide

  26. 他のプログラミング言語でのアーキテクチャテスト
    ● TNG/ArchUnitNET(C#)
    ● iternity/archlint.cs(C#)
    ● BenMorris/NetArchTest(.Net)
    ● sensiolabs-de/deptrac(PHP)
    ● carlosas/phpat(PHP)
    ● nazonohito51/dependency-analyzer(PHP)
    26

    View full-size slide

  27. アーキテクチャテストの例
    27

    View full-size slide

  28. 28
    @Test
    void DIP_依存性逆転の原則_を適用したレイヤードアーキテクチャ () {
    layeredArchitecture()
    .layer("ui").definedBy("com.example.presentation..")
    .layer("app").definedBy("com.example.application..")
    .layer("domain").definedBy("com.example.domain..")
    .layer("infra").definedBy("com.example.infrastructure..")
    .whereLayer("ui").mayOnlyBeAccessedByLayers("infra")
    .whereLayer("app").mayOnlyBeAccessedByLayers("infra", "ui")
    .whereLayer("domain").mayOnlyBeAccessedByLayers("infra", "app")
    .whereLayer("infra").mayNotBeAccessedByAnyLayer()
    .check(CLASSES);
    }

    View full-size slide

  29. 29
    @Test
    void DIP_依存性逆転の原則_を適用したレイヤードアーキテクチャ () {
    layeredArchitecture()
    .layer("ui").definedBy("com.example.presentation..")
    .layer("app").definedBy("com.example.application..")
    .layer("domain").definedBy("com.example.domain..")
    .layer("infra").definedBy("com.example.infrastructure..")
    .whereLayer("ui").mayOnlyBeAccessedByLayers("infra")
    .whereLayer("app").mayOnlyBeAccessedByLayers("infra", "ui")
    .whereLayer("domain").mayOnlyBeAccessedByLayers("infra", "app")
    .whereLayer("infra").mayNotBeAccessedByAnyLayer()
    .check(CLASSES);
    }

    View full-size slide

  30. 30
    @Test
    void ReportドメインはProcedureドメインからのみ依存される () {
    classes().that().resideInAPackage("com.example.domain.report..")
    .should()
    .onlyBeAccessed().byAnyPackage("com.example.domain.procedure..")
    .check(CLASSES);
    }

    View full-size slide

  31. 31
    @Test
    void ReportドメインはProcedureドメインからのみ依存される () {
    classes().that().resideInAPackage("com.example.domain.report..")
    .should()
    .onlyBeAccessed().byAnyPackage("com.example.domain.procedure..")
    .check(CLASSES);
    }

    View full-size slide

  32. ドメイン駆動設計にとっての
    アーキテクチャテスト
    32

    View full-size slide

  33. アーキテクチャテストの失敗は悪か?
    ● アーキテクチャテストはあるべき依存関係を表現したもの
    ● アーキテクチャテストは失敗しないはずのテスト
    ● アーキテクチャテストが失敗するとき
    ○ 実装誤り

    33

    View full-size slide

  34. アーキテクチャテストの失敗は悪か?
    ● アーキテクチャテストはあるべき依存関係を表現したもの
    ● アーキテクチャテストは失敗しないはずのテスト
    ● アーキテクチャテストが失敗するとき
    ○ 実装誤り
    ○ アーキテクチャを見直すサイン
    34

    View full-size slide

  35. ドメイン駆動設計を支えるアーキテクチャテスト
    ● ドメイン駆動設計の真髄は、設計⇔実装のフィードバックルー

    ● 実装によって設計も磨かれていく
    35

    View full-size slide

  36. ドメイン駆動設計を支えるアーキテクチャテスト
    ● ドメイン駆動設計の真髄は、設計⇔実装のフィードバックルー

    ● 実装によって設計も磨かれていく
    ● アーキテクチャも同じ
    ● アーキテクチャも一度決めて終わりではない
    ● アーキテクチャもシステムの成長とともに進化する
    36

    View full-size slide

  37. アーキテクチャの目的
    37

    View full-size slide

  38. この図は
    ● モノリシックなアプリケーション内部のドメインの依存関係?
    ● マイクロサービスアーキテクチャで実現されたアプリケーション
    の、サービス同士の依存関係?
    39

    View full-size slide

  39. この図は
    ● モノリシックなアプリケーション内部のドメインの依存関係?
    ● マイクロサービスアーキテクチャで実現されたアプリケーション
    の、サービス同士の依存関係?
    どちらもありえる。
    40

    View full-size slide

  40. ドメイン駆動設計という文脈で私たちが「ドメイン」と呼んでいるも
    のが、ありていに言うと、高凝集で疎結合な実装技術によって実
    現されていれば、システムとしてもビジネスとしても多くの選択肢
    が残される。
    モノリスからマイクロサービスへ、アーキテクチャを進化させる可
    能性も。
    41

    View full-size slide

  41. ソフトウェアが「ソフト」であるための選択肢を残す。
    それがアーキテクチャ。
    そのアーキテクチャが意図する依存関係を維持し、改善への気付
    きを得るためのアーキテクチャテスト。
    42

    View full-size slide

  42. 参考資料
    ● Books
    ○ エリック・エヴァンスのドメイン駆動設計(Eric Evans)
    ○ 実践ドメイン駆動設計(Vaughn Vernon)
    ○ Clean Architecture ―達人に学ぶソフトウェアの構造と設計(Robert C.Martin)
    ○ 進化的アーキテクチャ ―絶え間ない変化を支える(Neal Ford, Rebecca Parsons, Patrick
    Kua)
    ● Talks
    ○ ArchUnit で Java / Kotlin アプリケーションのアーキテクチャを CI する
    ■ https://speakerdeck.com/kawanamiyuu/jjug-ccc-2019-spring
    44

    View full-size slide