/jig-tutorial

JIGを使用した開発のチュートリアル

Primary LanguageJava

JIGチュートリアル

JIG を使用した開発のチュートリアルです。 以下の順番で進めます。

  1. プロジェクトの準備
  2. JIGの導入
  3. ビジネスルールの開発
  4. アプリケーションの開発

このチュートリアルを終えれば、コードをどまんなかに据えたモデリングができるようになります。

  • 🎓 は説明です。操作はありません。
  • 🏷 は本リポジトリのコミットです。やっていることがわからない場合などに使用してください。
  • 📝 はチュートリアルからは外れる内容ですが、知っておくと役立つことを書いています。

プロジェクトの準備

開発するアプリケーションのプロジェクトを作成します。ここでは以下を使用します。

  • JDK 11
  • JIG 2019.12.1
  • Gradle 6.0.1
  • Graphviz 2.43.0
  • Spring Boot 2.2.2.RELEASE

Javaプロジェクトの準備

このセクションは一般的なJavaプロジェクトの作成です。 Gradleでビルドできるなら、どのような方法で作成しても構いません。

GradleのBuild Init Pluginを使用してプロジェクトを作成します。

$ gradle init --type java-library \
    --test-framework junit-jupiter \
    --dsl groovy \
    --project-name jig-tutorial \
    --package jig.tutorial

Gradleのbuildタスクを実行してください。

$ ./gradlew build

BUILD SUCCESSFUL in 5s
4 actionable tasks: 4 executed

上記のように BUILD SUCCESSFUL が出力されればOKです。JDKとGradleの確認ができました。 お好きなIDEに取り込んでください。

🏷 b61193ca161c711066dd424b29badae963d6bd24

🎓 想定するパッケージ構成

JIGが標準でサポートするアーキテクチャは ドメインを独立させる Isolating the Domain です。 Isolating the Domainのパッケージ構成は以下の通りです。

.
+-- presentation
|    +-- controller
|    +-- view
+-- application
|    +-- service
|    +-- repository
+-- infrastructure
|    +-- datasource
|    +-- transfer
+-- domain
     +-- type
     +-- model

JIGではこれらを「ビジネスルール」と「アプリケーション」に分類します。

  • アプリケーション: 三層。 presentation, application, infrastructure パッケージ。
  • ビジネスルール: ドメインモデル。 domain パッケージ。

📝 Isolating the Domainに準拠していなくても、JIGドキュメント自体の出力は可能です。

JIGの導入

JIG Gradle Plugin を導入します。

build.gradlepluginsorg.dddjava.jig-gradle-plugin を追加します。

plugins {
    id "org.dddjava.jig-gradle-plugin" version "2019.12.1"
}

JIGドキュメント出力時にコンパイルするよう、 build.gradle に以下を追加します。

[compileJava, processResources]*.mustRunAfter(clean)
jigReports.dependsOn(clean, classes)

jigReports を実行して BUILD SUCCESSFUL となればOKです。

$ ./gradlew jigReports

> Task :jigReports
skipped ...

BUILD SUCCESSFUL in 11s
1 actionable task: 1 executed

🏷 a643f07c5762d49e7166a58b48332c5e9c5df5e3

📝 jigReports の実行はIDEのワンアクションで行えるようにしておくとスムーズです。

📝 Gradleを使用していない、Gradleのバージョンが古いなどで JIG Gradle Plugin が使用できない場合は コマンドライン版 を使用して出力できます。

環境の確認

JIGはダイアグラム出力にGraphvizを使用しています。 インストールされていることを確認してください。

$ dot -V
dot - graphviz version 2.43.0 (0)

JIG Gradle Plugin 2019.12.2 以降なら verifyJigEnvironment タスクで実行環境を検証できます。

$ ./gradlew verifyJigEnvironment

> Task :verifyJigEnvironment FAILED
-- JIG ERROR -----------------------------------------------
+ 実行可能なGraphVizが見つけられませんでした。
+ dotにPATHが通っているか確認してください。
+ JIGはダイアグラムの出力にGraphVizを使用しています。
+
+ GraphVizは以下から入手できます。
+     https://www.graphviz.org/
------------------------------------------------------------

🎓 JIGドキュメントの紹介

JIGドキュメントには以下があります。

  • ビジネスルールドキュメント
    • BusinessRuleList
    • PackageRelationDiagram
    • BusinessRuleRelationDiagram
    • CategoryDiagram
    • CategoryUsageDiagram
  • アプリケーションドキュメント
    • ApplicationList
    • BranchList
    • ServiceMethodCallHierarchyDiagram
    • BooleanServiceDiagram
  • アーキテクチャドキュメント
    • ArchitectureDiagram
    • PackageTreeDiagram

これらを使用して開発をすすめます。

ビジネスルールの開発

ビジネスルールを開発してみましょう。 チュートリアルでは「商品の注文を受けて出荷する」を扱います。

001

はじめてのJIGドキュメント

はじめに jig.tutorial.domain.model.product パッケージに商品クラスを作成します。 中身は空で構いません。

package jig.tutorial.domain.model.product;

public class Product {
}

作成できたらGradleで jigReports タスクを実行します。 ./build/jigbusiness-rule-relation.svg が出力されます。

002

🏷 ce64e504f95e1d72b35412e24493bfbbdbc91a85

クラスの関連で開発する

商品としての関心ごとを挙げ、全てに対するクラスを作成していきます。 ここでは商品名と定価を持つとします。

先ほどと同様にNameクラスとPriceクラスを作成します。

003

🏷 65467f34507d197d5a50096d1fb75fd119e21f7e

商品名と定価は商品が使用するので、Productのフィールドに追加します。

public class Product {
    Name name;
    Price price;
}

004

🏷 48470763c78c7f3aa27e5bfa47256bfccff11119

Javadocコメントに日本語名を記述します。

/**
 * 商品
 */
public class Product {

005

🏷 4a072917cd9caeba8339870a34fb393d0a22d6a3

パッケージの関連で開発する

次に注文と出荷を開発します。 商品と同様にパッケージとクラスを作成します。

  • 注文: jig.tutorial.domain.model.order
  • 出荷: jig.tutorial.domain.model.shipment

006

🏷 4a0dd1192fd2b1adbef39c410bf71c868d4dcb94

注文は商品、出荷は注文と商品を扱います。それぞれフィールドに追加します。

007

パッケージ間の関連ができると package-relation-depth*.svg が出力されます。 和名は package-info.java のJavadocで記述できます。

008

🏷 36f089f4f049bc13db7912afe3cc467da33176d6

区分で開発する

取り扱うステータスを enum で列挙します。

  • 商品在庫: 在庫あり、在庫なし
  • 注文ステータス: 注文受付済み、出荷済み、キャンセル

enumcategory.png に出力されます。

009

商品在庫を商品のメソッドで返します。

public class Product {
    ...

    public ProductStock productStock() {
        return ProductStock.在庫あり;
    }

使用が category-usage.png に出力されます。

010

🏷 37f68c5b0f669bab4433de7ec634b01ec5a69d59

ここまでの設計は business-rule.xlsx で一覧できます。

011

012

パッケージを相互依存させてみる

相互依存があると赤矢印が出力されます。

013

相互依存の原因となっているクラスは bidirectionalRelations-depth*.txt に出力されます。

パッケージをネストさせてみる

パッケージをネストするとパッケージの深さごとにパッケージ関連図が出力されます。

014

💪 チャレンジ

ビジネスルールを自由に開発してみましょう。

使用例: 言葉ファーストでの開発

ドメインの言葉でクラスを作成してJavadocに日本語名を書いていきます。

関連すると思われるクラスをフィールドやメソッドなどで使用しながらラフに関連を設計します。 このアプローチでは処理は二の次で構いません。

ある程度関連が設計できたら処理を記述していきます。 想定外の依存が発生するなどぎこちなくなるとJIGドキュメントからフィードバックが得られます。

アプリケーションの開発

アプリケーションを開発してみましょう。 このチュートリアルではSpringBootを使用します。

Spring Bootの導入

最低限 spring-context さえあれば開発は可能です。

spring-boot-starter-web を依存関係に追加します。

dependencies {
    implementation platform('org.springframework.boot:spring-boot-dependencies:2.2.2.RELEASE')
    implementation("org.springframework.boot:spring-boot-starter-web")
}

🏷 3022c08f6b43111ab67dc0c467e0e67b4d6425b4

アプリケーションを開発する

@Controller, @Service, @Repository を付与したクラスを作成します。

  • jig.tutorial.presentation.controller.SampleController
  • jig.tutorial.application.service.SampleService
  • jig.tutorial.application.repository.SampleRepository
  • jig.tutorial.infrastructure.datasource.SampleDataSource

クラスを作成したら商品を取得するメソッドを作成します。

続いてJavadocを記述します。JIGはJavadocから以下を読み取って使用します。

  • Controller のクラス名
  • Service のクラス名、メソッド名
  • Repository のクラス名

サービスのメソッド呼び出しが service-method-call-hierarchey.svg に出力されます。

015

🏷 de6ef6ead230fb8d9a349f4a12c09204c2197fd4

ここまでの設計は application.xlsx で一覧できます。

💪 チャレンジ

アプリケーションを自由に開発してみましょう。 必要に応じてビジネスルールを充実させていきましょう。

他のJIGドキュメントからのフィードバック

ArchitectureDiagram architecture.svg には、アーキテクチャブロックの関連が出力されます。 domainから他への依存のような、意図しない依存が発生していないかの確認に役立ててください。

016

BooleanServiceDiagram は真偽値を返すサービスを作成した場合に出力されます。 サービスが真偽値を返すと、呼び出し元で機械的な判定を行う必要があります。

BranchList branches.xlsx はアプリケーションの各メソッドの分岐数です。 分岐はビジネスルールの可能性があります。 ビジネスルールであればアプリケーションからビジネスルールに移動し、ドメインモデル貧血症を予防しましょう。

付録: JIGを使用した開発サイクル

JIGでの開発は以下のようになります。

  • 頭の中やホワイトボードなどで描く
  • コードで書いてみる
  • JIGドキュメントを眺める
  • フィードバックを得ながら考える
  • コードで書いてみる
  • JIGドキュメントを眺める
  • ...(以下ループ)

017

参考: JIGを使った設計

付録: JIGを使用しているリポジトリ