「コードで理解するDDDの戦略的設計・戦術的設計のつながり」DDD勉強会に参加してきた

「コードで理解するDDDの戦略的設計・戦術的設計のつながり」DDD勉強会に参加してきた

# 概要

8月20日(月)に表題のDDDの勉強会に参加してきた。

コードで理解するDDDの戦略的設計・戦術的設計のつながり


# 参加に至った経緯

この勉強会に参加しようと思ったきっかけについて書いていく。

直近で携わっていたWebアプリケーションのサーバーサイドの設計は、Railsの規約に則ったMVCの設計に加え、Service層、WebService層、Vo層を設けて実装していた。

このような設計について、「なぜこのような設計にしているのか?」「なぜこの設計だと嬉しいのか?」という疑問を抱いていた。そもそも上長がなぜこのような設計にしていたのか?この設計思想の根源はどこにあるのか?について調べていると、ドメイン駆動設計にあるのかなと思った。

そして、ドメイン駆動設計について調べていく中で松岡さんのブログ(little hands’ lab - ドメイン駆動設計を布教したい)に行き着いた。


# 勉強会に参加してみた率直な感想

最初の一時間を過ぎてからは、頭が追いつかなかったほど難かったです。

これは完全にぼくの問題で、松岡さんの説明は初学者の方に対しても紳士でした。

ぼくの問題というのは、

  • Javaの知識が皆無だった。
  • モデリングの知識がほぼなかった。
  • DDDについて理解が不十分だった。

などです。


# 内容をざっくりまとめてみる

## DDDする上でのTips

  • 英語でググること

日本語の情報よりも英語での情報の方が圧倒的に多いそう。

## DDDが生きるアプリケーションとは?

DDDは銀の弾丸ではない。
適切な場所で適切に使用してこそ生きる。

× 単純なCRUD
× 機械学習
○ 複雑なニーズ

単純なCRUDのWebアプリケーションを実装するのであれば、Railsなどを使用し、そのMVCモデルに従った方が良い。

## モデルとは何か?

現実世界の問題をそぎ落として抽象化したもの。
ソフトウェア化する対象である「ドメイン」を抽象化したもの。

## 理解の順番を意識する

設計を戦術的設計と戦略的設計の二つに分ける。

戦術的設計:

ドメインモデリングの前提を揃えるための、モデリング対象を定義する原則と手法(コアドメイン/サブドメイン、境界付けられたコンテキスト、コンテキストマップ等)

戦略的設計:

モデルを具体的に表現するためのパターン(エンティティ、レポジトリ、レイヤードアーキテクチャ等)

「モデリング」をしっかり考えるならば避けて通れないが、実装イメージがない状態では、どのようにモデリングすれば良いのかがわからない。

そのため、理解の順番は、
戦術的設計 → 戦略的設計
が良い。

## 良い設計とは?それを測る指標とは?

そもそも悪い設計とはどんなものだろうか?

著名な書籍である「Clean Code」の著者 Uncle Bob の記事を参照すると、

  • Rigidity(硬さ)
  • Fragility(脆さ)
  • Immobility(移植性のなさ)

が挙げられている。

そのため、良い設計とは、

  • バグらない
  • 拡張性が高い
  • 可読性が高い

などが挙げられる。

これらの要素は、凝集度と結合度という二つの指標に集約できる。
つまり、高凝集、低結合であることが良い設計である。

凝集度とは:

モジュール内の要素同士がどれだけ関連しているかを示す指標

凝集度が低い状態とは、クラスの責務が不明確であり、
凝集度が高い状態とは、クラスの責務が明確で単一である。

結合度とは:

モジュール間の依存性の高さを示す指標

結合度が高い状態とは、モジュール同士が依存している状態であり、
結合度が低い状態とは、モジュール同士が依存していない状態。

## ビジネスロジックとは何か?

ざっくりいうとビジネスロジックとは、そのアプリケーションの「仕様」。

ただ、一般的なビジネスロジックでは一つの性質として語られることが多いが、プログラミングの世界の中では「ドメイン知識とユースケース」の2つの性質に分けることができると指摘されている。

これは、問題解決を行おうとする対象が、Webアプリケーションで解決する場合と、現実世界で解決する場合で異なるから。ドメイン知識はソフトウェアがなくても現実世界に存在するが、ユースケースはソフトウェアがなければ存在しない。

ドメイン知識:

ソフトウェア化する対象領域に存在するルール

ユースケース:

ユーザーとソフトウェア間の相互関係を起こすアクション

## Webアプリケーションにおける責務はどのように分けるべきか?

この解説が非常におもしかった。理解できたかどうかは怪しい。
実際に書かれたコードを見ながらそれぞれの設計のメリット・デメリットを比較した。

  • 1層アーキテクチャ責務(全て一つに)
  • 2層アーキテクチャ責務(Presentation層をBusinessLogic/DataAccess層と分ける)
  • 3層アーキテクチャ責務(さらにBusinessLogic層とDataAccess層を分ける)
  • 4層アーキテクチャ責務(さらにBusinessLogic層をUseCase層とDomain層に分ける)
  • 3層+ドメインモデルアーキテクチャ(※理解できませんでした)
  • オニオンアーキテクチャ

※各オブジェクトは、

  • クライアントとの入出力(Presentation)
  • ユースケースの実現(UseCase)
  • ドメイン知識の反映(Domain)
  • データベースとの入出力(DataAccess)


# RailsのMVCモデル設計について思うこと

最後に、昨今、何かと批判されがちなRailsに対して一言添えて結びとしたい。

MVCモデルの設計には十分なメリットを享受できる場合がある。

  • Railsはあらゆるアプリケーションに向いたフレームワークとして作られていない
  • Railsはクリーンさよりも便利さを重要視している
  • DHHは汎用的な設計のための自由度よりも利便性のためのある意味の割りきりを行なっている

Railsは以下のようなWebアプリケーションの実装に向いている

  • シンプルなCRUDの仕様
  • 開発に携わるエンジニアの数は少なければ少ないほどよい


参考サイト