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

#ooc_2020 / ドメイン駆動設計を支えるアーキテクチャテスト / Object-Ori...

Yu Kawanami
February 16, 2020

#ooc_2020 / ドメイン駆動設計を支えるアーキテクチャテスト / Object-Oriented Conference 2020

Yu Kawanami

February 16, 2020
Tweet

More Decks by Yu Kawanami

Other Decks in Technology

Transcript

  1. 自己紹介 • かわなみゆう • @kawanamiyuu • 株式会社ラクス / Lead Engineer

    • HR x SaaS の開発 • Java (Spring Boot, Doma) / Vue.js / Puppeteer • 自動テスト(が書きやすい設計を考えながらコード) を書くのがすき 3
  2. アーキテクチャとオブジェクト指向設計原則 • (乱暴に言うと)Layer Architecture も Clean Architecture も 、DDD のような設計論も、依存関係を適切に設計したいだ

    け • その礎としてのオブジェクト指向設計原則 ◦ 単一責任の原則(SRP) ◦ 依存関係逆転の原則(DIP) 15
  3. 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
  4. 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); }
  5. 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); }
  6. 32 @Test void ドメイン層はWeb実行環境に依存しない () { noClasses().that().resideInAPackage("com.example.domain..") .should() .dependOnClassesThat().resideInAPackage("javax.servlet..") .check(CLASSES);

    } @Test void ドメイン層はWebアプリケーションフレームワークに依存しない () { noClasses().that().resideInAPackage("com.example.domain..") .should() .dependOnClassesThat().resideInAPackage("org.springframework..") .check(CLASSES); }
  7. 33 @Test void ドメイン層はWeb実行環境に依存しない () { noClasses().that().resideInAPackage("com.example.domain..") .should() .dependOnClassesThat().resideInAPackage("javax.servlet..") .check(CLASSES);

    } @Test void ドメイン層はWebアプリケーションフレームワークに依存しない () { noClasses().that().resideInAPackage("com.example.domain..") .should() .dependOnClassesThat().resideInAPackage("org.springframework..") .check(CLASSES); }
  8. 41

  9. 参考資料 • Books ◦ エリック・エヴァンスのドメイン駆動設計( Eric Evans) ◦ Clean Architecture

    ―達人に学ぶソフトウェアの構造と設計( Robert C.Martin) ◦ 進化的アーキテクチャ ―絶え間ない変化を支える( Neal Ford, Rebecca Parsons, Patrick Kua) • Talk ◦ JJUG CCC 2019 Spring ▪ ArchUnit で Java / Kotlin アプリケーションのアーキテクチャを CI する ▪ https://speakerdeck.com/kawanamiyuu/jjug-ccc-2019-spring • Blog ◦ ドメイン駆動設計#1 Advent Calendar 2019 ▪ 6日目:ドメイン駆動設計を支えるアーキテクチャテスト ▪ https://tech-blog.rakus.co.jp/entry/20191206/java 47