新説 ドメイン駆動開発 ~ 序

# 概要
「ドメイン駆動開発(Domain-Driven Development; DDD)」とは何か改めて考えてみた.
DDDは大規模なエンタープライズ系のシステムやソフトウェアの設計の方法論として紹介されることが多いが, **組込みアプリの開発 や MLアプリ のほか, LLMによるソフトウェア開発の自動化 にも重要な役割を果たすのではないか**, という仮説を本記事では唱える.
IoT, ML, LLM 時代における DDD の役割の再定義を試みる.

# はじめに
DDD は通常 「ドメイン駆動**設計**(Domain-Driven **Design**)」を指すが, 開発プロセスの設計以外の領域にも適用されるべきものという意味を込めて, この記事ではあえて  「ドメイン駆動**開発**(Domain-Driven **Development**)」にしている. もっともDDDの原典である Eric Evans の著書 [^1][^2] でも特に設計工程だけに限った話をしているわけではないので, 原典に倣って Design としても良いと思ったが, Design というと設計工程を想起する人も多いかと思ったこともあり..

個人的にはDDDは Web系やエンタープライズ系のシステムの領域で, かつ, デザインパターンの文脈で 語られることが多い印象. 例えば, MVC Framework, Clean Architecture, CQRS, Event-Sourcing などのキーワードがDDDの記事でよく見かけられる. 本記事ではそういった古き良き伝統ある系譜に連なるDDDの文脈とは別の観点でDDDの役割について考察しており, その意味でタイトルに "新説" と銘打っている. 

まず, 本記事では DDD の概要について自分なりに整理する.
以降の記事ではいくつかのテーマごとにDDDについて考察するが, もしかしたらすでにある議論の後追いや焼き直しになる恐れもあるので, できるだけ既往の議論をサーベイし, それらを踏まえた上でまとめていこうと思う.

# DDD の概要
まず, DDD の定義や特徴, メリット, デメリットなどについてまとめる.
*あくまで個人的な所感なので, 詳細は [参考資料](#参考資料) を参照されたい.

## 定義
残念ながら Eric Evans の著書を見ても, DDD(ドメイン駆動設計) とは何か, ということがあまり明確に定義されていなかった.
調べてみるとありがたいことにDDDとは何かについてまとめてくれている記事が見つかった[^3]が, やはりバシッと明文化された公式の定義がないとのこと.

かなり単純化されていて浅い表現だが, 自分なりには以下のように解釈している.
```
ドメイン駆動設計/開発とはドメインモデルを構築し, それを基にソフトウェアを設計/開発する思想.
```

本質的には, 単に開発プロセスにおける中間成果物として ドメインモデル を追加するだけにとどまらず, ドメインエキスパートとのコミュニケーションや実装からのフィードバックを含むイテレーションを経て, ドメインモデルを継続的に洗練させ, それらの概念を開発チームメンバー全体に普及させ, 実装に反映させる, というところまでが求められる模様.
ただ, Evans 自身も実際のプロジェクトでそれを実践するのは一筋縄ではいかないと感じているらしい.

:::note
**[用語解説] ドメイン**
ドメインとはソフトウェアが問題解決すべき対象とする領域のこと.
例えば, 小売り, 金融, 輸送, 自動車, 船舶, 航空 など.
:::

:::note
**[用語解説] ドメインモデル**
ドメインモデルは, 対象とするドメインの **概念** や **概念間の関係性**, **ルール** などをモデル化したもの.
典型的には UML のクラス図で表現されるが, これはオブジェクト指向プログラミングのためのクラス図とはまた役割が異なる. 例えば, interface, abstract class, private 修飾子 などは指定すべきではない.
:::

## 特徴
1. 統一された 語彙 (ユビキタス言語) や ドメインモデル に基づいてソフトウェア開発を行う.
2. ドメイン固有の概念やロジック (ドメイン層) を ソフトウェア固有の概念やロジック (アプリ層 や インフラ層 などと呼ばれる) から分離し, ドメインの問題の検討に専念できるようにする.

2点目はソフトウェア工学においてよく語られる **関心事の分離 (Separation of Concerns)** の原則に関連する. ソフトウェアが複雑化する要因としては, ドメイン自体が持つ複雑性によるもの と ソフトウェア要素の複雑性によるものがあるといわれており, それらを分離して検討できるようにする.
ソフトウェア開発固有の概念は ドメイン層から排除し,　アプリ層 や インフラ層 に含められるべき. 例えば, Adaptor, Converter, Facade, ArrayList/LinkedList, SQL/No-SQL, nginx/httpd, React/Angular, xml/json などはソフトウェア開発固有の概念なので, ドメイン層からできるだけ排除すべき. ただし, これらのソフトウェア技術を対象のドメインとして取り扱う場合を除く.
かつ, ドメイン層はこれらのソフトウェア開発固有の概念に依存しない設計になっていることが望ましい. この点に関しては, クリーンアーキテクチャ[^4] など, これを実現するためのデザインパターンがいくつか提案されている.

## メリット / デメリット
**メリット**
- 統一された 語彙 や ドメインモデル により, ステークホルダー間のコミュニケーションを円滑化 (情報伝達によるロスを最小限に).
  - 無曖昧性の向上 (要求や仕様, 設計の記述における曖昧さを低減できる)
  - 可読性の向上 (設計書やコードの責務が把握しやすくなる)
  - 検証可能性の向上 (レビューしやすくなる. テスト基準が明確になる)
- データモデルの品質を向上.
  - 機能性の向上 (対象とするドメインの目的, ないし, 機能要件を達成しやすいデータモデルになる)
  - 一貫性の担保 (対象とするドメイン固有の用語法などに起因する概念の不整合に気づきやすくなる)
  - 相互運用性の向上 (目的毎, 組織毎に存在するデータモデル間の互換性を保持しやすくする)
- アプリケーション固有の概念やロジックの乱立を防止.
  - 保守性の向上 (SQL/No-SQL などの特定の技術に依存しないしなやかな設計に)
- 対象とするドメインの新たなユースケースやサービスに対応しやすくする.
  - 拡張性の向上 (対象とするドメインに即したデータモデルとなっているため, 例えば, あるデータ間の関係をたどって検索や処理することでユースケースに対応できる場合に, それらの必要な情報が提供されやすい)

**デメリット**
- ドメインモデルを整備するのにコストがかかる.
- 開発者がドメイン駆動設計/開発の流儀や作法を習得するのにコストがかかる. これらを理解していないと適切にユーザからドメイン知識を適切に引き出せなかったり, モデル化が適切に行われなかったり, モデルが実装に反映されなかったりして, その結果, 上記のような恩恵が得られない. 

## どのような場合に役立つか
総じて, DDDは継続的に保守や拡張する必要がある大規模なシステムの開発において特にそのメリットを発揮する可能性がある. ドメインモデルをイテレーションを通じて進化させていくという部分は XP(eXtreme Programming) や アジャイル開発 とも親和性が高いらしい.
一方で, デモ用のモックアップアプリなどの一点もののアプリケーションの開発 や 小規模なアプリケーションの開発の場合には, データモデルを基にUIやDBスキーマを設計するという開発手順として利用する分には利用価値はあるかもしれないが, それ以上にユビキタス言語を確立したり, ドメイン層を他の層から分離して抽象化し, 保守しやすいしなやかな設計にすることによるメリットはあまりないかもしれない. 

## 今後のDDDの姿
個人的にはDDDの在り方に影響を与えうる側面としては, 大きく分けて, Language, Technology, Application, Process の4つがあると考えている.

![DDD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3787917/4291a3d4-11ae-fc86-fa8f-f5741f25414a.png)

**Language** はドメインモデルの表現方法を指し, Notation (記法) や Representation (表現様式) と言い換えてもよい. ドメインモデルの記述は典型的にはUMLで行われることが多い印象だが, 従来の graphical notaion (図記法) に加えて, plantuml などの簡易的な textual notation (テキスト記法) が発展してきており, 導入や処理が容易になってきている. また, UML以外にも, 概念間のマッピングやモデルの統合が可能で, 拡張性や相互運用性に優れたOWLなどの記述言語も普及してきている. これらの言語や支援ツールの発展により, ドメインモデルの構築や統合, 検証, 共有などの利活用がより促進されることが想定される.

**Technology** はドメインモデルの整備や活用を支援する技術を指す. ドメインモデルの作成にはドメイン知識の獲得や形式化, 構造化, 検証などのタスクが含まれ, これらのタスクは基本的には人が担っていた. LLMの活用によって, これらのタスクを(一部でも)自動化/効率化できる可能性があり, DDDのデメリットがかなり緩和できる可能性がある.

**Application** はDDDの適用対象の領域を指す. エンタープライズ系やWebアプリ系の開発で主に活用され, 実績が蓄積されてきた印象があるが, 機械学習(Machine Learning; ML)や自動運転などを含むIoT(Internet of Things)系の領域にも有効に活用できる可能性があると個人的には考えている. というのも, MLの領域では運用環境のドメインを十分に理解し, 運用環境で想定される条件がどれだけ網羅されているかを把握することが(特にセーフティクリティカルなシステムの場合には)求められる. 学習やテストに用いられるデータセットの仕様記述などにドメインモデルが役立つと考えられる. IoTの領域では個々のエッジ端末のレベルではメリットを発揮しづらい恐れもあるが, 様々な種類の端末が System of Systems を構成する場合などに, 共通のドメインモデルがあることでデータの相互運用性の向上を図ることができる可能性がある.

**Process** はDDDの適用対象の開発工程を指す. DDDは本来ドメイン駆動設計の略語であり, デザインパターンの文脈で語られることが多いことからも, 設計工程が主な適用対象となっている印象がある. ドメインモデル(ないし, ユビキタス言語)は共通の用語法を提供することから, 要求仕様の記述にそれらの用語法を適用することで曖昧性を排除する役割が見込まれる. その他, STPAなどのシステムの運用環境を含むリスクアセスメントにおいてもドメインモデルが(明示化された概念の範囲で)網羅的なリスクの識別に寄与することが考えられる. 

以降の記事ではこれらのテーマを詳細に掘り下げて考察していこうと思う.

# 連載記事のテーマ (予定を含む)
- 新説 ドメイン駆動開発 ~ そもそもDDDって何? その歴史..
- [新説 ドメイン駆動開発 ~ DDD & LLM](https://qiita.com/Yocote0111/items/9b384ff67bfc09ed883c)
- 新説 ドメイン駆動開発 ~ DDD for ML
- 新説 ドメイン駆動開発 ~ DDD for IoT
- 新説 ドメイン駆動開発 ~ ドメインモデルと記述言語
- 新説 ドメイン駆動開発 ~ ドメインモデルと要求仕様記述
- 新説 ドメイン駆動開発 ~ ドメインモデルとリスクアセスメント
*その時の興味によって変わる可能性あり.

# 参考資料
[^1]: [エリック・エヴァンスのドメイン駆動設計](https://www.shoeisha.co.jp/book/detail/9784798126708)
[^2]: [DDD Reference](https://www.domainlanguage.com/ddd/reference/)
[^3]: [[DDD]ドメイン駆動設計の定義についてEric Evansはなんと言っているのか](https://qiita.com/little_hand_s/items/7288a0b3dd5dfb1a4c35)
[^4]: [The Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)

<!-- - OOP, DOP, AOP, SOA -->