[DDD]ドメイン駆動設計で実装を始めるのに一番とっつきやすいアーキテクチャは何か

DDD連載記事
* [なぜDDD初心者はググリ出してすぐに心がくじけてしまうのか](http://little-hands.hatenablog.com/entry/2017/09/24/005903)
* [ドメイン駆動設計の定義についてEric Evansはなんと言っているのか](http://little-hands.hatenablog.com/entry/2017/09/27/014403)
* [モデルでドメイン知識を表現するとは何か](http://little-hands.hatenablog.com/entry/2017/10/04/201201)
* [ドメイン駆動設計で実装を始めるのに一番とっつきやすいアーキテクチャは何か](http://little-hands.hatenablog.com/entry/2017/10/04/231743)
* [ドメイン駆動 + オニオンアーキテクチャ概略](http://little-hands.hatenablog.com/entry/2017/10/11/075634)

# 背景・前提
[なぜDDD初心者はググリ出してすぐに心がくじけてしまうのか](http://little-hands.hatenablog.com/entry/2017/09/24/005903)の記事で、

>ネット上の文献で紹介されるアーキテクチャが様々なものとなっているのです。IDDDではヘキサゴナルアーキテクチャというものが掲げられていましたが、それを進化させたオニオンアーキテクチャ、クリーンアーキテクチャなどの有名な亜種が存在します。
>これが実装に着手する際に非常に大きな混乱を呼ぶのです。文脈の理解、採用するアーキテクチャの選定に時間を取られることでしょう。

と書きました。こちらに対して、私が「一番とっつきやすい」と考えるアーキテクチャを紹介します。

前提としてですが、***完全に個人的な経験に基づく私見***になります。

DDDの理論の中で、アーキテクチャに関しては<a target="_blank" href="https://www.amazon.co.jp/gp/product/4798121967/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4798121967&linkCode=as2&tag=majackyy-22&linkId=7699973b1a98ab103afb5d261de7bfb1">エリック・エヴァンスのドメイン駆動設計</a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=majackyy-22&l=am2&o=9&a=4798121967" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />(以下原典)と<a target="_blank" href="https://www.amazon.co.jp/gp/product/479813161X/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=479813161X&linkCode=as2&tag=majackyy-22&linkId=aff868b58c9e780a12c6e0c21d99699d">実践ドメイン駆動設計 (Object Oriented SELECTION)</a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=majackyy-22&l=am2&o=9&a=479813161X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />(以下IDDD)とでも異なったものが紹介されており、唯一の正解というものは提示されていません。アーキテクチャは各プロジェクトの判断に委ねられているものであり、合う合わないはプロジェクトの要件やメンバーによって異なります。

ただ、それだけではまず始める時にどう着手すればよいか迷ってしまうと思うので、*「初学者が手をつけるならこれが良いのでは」*というものを私が提案する形になります。ご了承ください。

# 候補となるアーキテクチャと、その関係性

ネットでDDDの記事を漁るとだいたい以下のものがでてくると思います。

1. レイヤードアーキテクチャ
2. ヘキサゴナルアーキテクチャ
3. オニオンアーキテクチャ
4. クリーンアーキテクチャ

これらの概略を簡単にお話しします。

# レイヤードアーキテクチャ
<img width="453" alt="Layered.png" src="https://qiita-image-store.s3.amazonaws.com/0/30489/178da69e-b11a-591e-3430-128a5559ed75.png">

原典で紹介されているアーキテクチャ。
従来の3層アーキテクチャに比べて、Domain層を確立させ、そこにドメインロジックを凝集させよう、という発想のものです。

## ヘキサゴナルアーキテクチャ
<img width="676" alt="Hexagonal.png" src="https://qiita-image-store.s3.amazonaws.com/0/30489/f5c66a12-a500-a536-5805-eafcebab84ce.png">

IDDDで紹介されているアーキテクチャ。別名「ポートアンドアダプターアーキテクチャ」。
元は[こちらのブログ](http://alistair.cockburn.us/Hexagonal+architecture)で2005年に提唱されたものです。

実は***「ヘキサゴナル、オニオン、クリーン」の3つは、本質的には全く同じ***です。

思想としてはこのヘキサゴナルで完成されているんですよ。責務の区切り方と名称が少しずつ違うだけなんです。じゃあ、ヘキサゴナルでいいじゃないかって？

そうです、本質的には基本的にヘキサゴナルでよいし、結果的に同じ設計をしていることになるんです。

ただし・・・・

***この図を見ても、実装イメージが湧かなくないですか？***

私はこれがポイントだと思っていて、このわかりづらさがIDDDを読んだ人が手をすぐ動かせない理由ではないかと考えているのです。

結論を変な位置でいうと、***私のオススメはオニオンアーキテクチャ***です。これは本質的には同じでも、責務の区切りと名称を変えた結果 直感的にわかりやすくなっているので、最初の導入はこの図を見ながらやるのが良いと思っています。

では、次にそちらを紹介します。

## オニオンアーキテクチャ
ヘキサゴナルアーキテクチャを受けて、2008年に[こちらのブログ](http://jeffreypalermo.com/blog/the-onion-architecture-part-1/)で提唱されたのがオニオンアーキテクチャです。

<img width="480" alt="Onion.png" src="https://qiita-image-store.s3.amazonaws.com/0/30489/81fcfd95-2ce1-82a8-db69-8618338a5f22.png">
同じ構造を、平らに表現したのが以下の図です。
<img width="660" alt="Onion(Flattened).png" src="https://qiita-image-store.s3.amazonaws.com/0/30489/843952a5-fd2e-cdd7-245d-47d95135a2af.png">

少〜し、どういう構造にするのかイメージが湧いてきませんか？
詳細はこの後説明するのですが、ポイントは***依存関係逆転の原則***によってDomain層がInfrastructure層に依存しなくなっていることです。これによりDomain層のモデルが特定のライブラリなどに依存しない形の実装になるのです。

これはヘキサゴナルアーキテクチャでも全く同じ思想なのですが、概念図からはそのことが読み取りづらいのです。そのため、図を見たときの直感的なわかりやすさから、私は最初に着手するにあたってはオニオンアーキテクチャを推しています。

変な順番になってしまいましたが、比較のためにクリーンアーキテクチャも紹介します。

## クリーンアーキテクチャ
ヘキサゴナル、オニオンやその他のアーキテクチャを受けて、2013年に概念を統合しようとしたのがクリーンアーキテクチャです。[こちらのブログ](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html)で提唱されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30489/ede07478-3be1-732a-82b3-c3558f4c9e49.png)
画像は[同ブログ](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html)から引用

同じく同心円が重なっている構造からわかるように、基本的に言っていることは同じです。違いとしては単語だけだと思っています。

クリーンアーキテクチャは、Androidアプリケーションのアーキテクチャとして、DDDとは関係なく使われている記事がちらほら見受けられました。

これは全くもって好みになるのですが、「UseCase層」というレイヤに何を書くのかわかりにくい点、「Domain層」ではなく「Entity層」というネーミング(DDD的にはEntityはDomain層の一部なので、収まりが悪い)から、私はオニオンアーキテクチャの方がよいと思っています。

これがしっくり来る方はクリーンアーキテクチャのネーミングを採用すれば良いかと思います。

# アーキテクチャを使ってどう実装するのか
ドメイン層にどのようにふるまいを詰め込むのか、について、
[【DDD】モデルでドメイン知識を表現するとは何か](http://little-hands.hatenablog.com/entry/2017/10/04/201201)
こちらの記事でサンプルコード付きで紹介しています。

<img width="660" alt="Onion(Flattened).png" src="https://qiita-image-store.s3.amazonaws.com/0/30489/843952a5-fd2e-cdd7-245d-47d95135a2af.png">

記事内のTaskエンティティがDomainModel、TaskRepositoryがDomainService、TaskApplicationがApplicationに該当します。
こうして見てみると、結構シンプルですし、レイヤーの名前と内容がイメージしやすいのではないでしょうか。

そういったわけで、私はDDDを最初に説明するときは、オニオンアーキテクチャと先ほどのようなサンプルコードの説明をするところから始めるようにしています。

オニオンアーキテクチャ、依存性の逆転については、また別の記事でもう少し深堀りしてみたいと思います。

# 後続記事
[ドメイン駆動 + オニオンアーキテクチャ概略](https://qiita.com/little_hand_s/items/2040fba15d90b93fc124)
こちらぜひご覧ください。

### もっと詳しく知りたい方は

初めてDDDを学ぶ方、もしくは実際に着手して難しさにぶつかっている方向けの書籍を出しました。

[ドメイン駆動設計 モデリング/実装ガイド](https://little-hands.booth.pm/items/1835632)

迷子になりがちな「DDDの目的」や「モデル」の解説からはじめ、
具体的なモデリングを行い実装まで落とす事例を元に、DDDの魅力や効果を体感することを目指します。

この本の「第5章 アーキテクチャ」では、この記事の内容をさらに詳細に解説しています。よろしければお求めください。


【2021/10/30新刊】

DDD解説書の新刊を執筆しました。
重要トピック「モデリング」「集約」「テスト」について詳細に解説し、その他のトピックでは頻出の質問への回答と具体的なサンプルコードをふんだんに盛り込みました。現場で実践して、困っていることがある方はぜひこちらもご覧ください。

https://little-hands.booth.pm/items/3363104

Twitterでも、DDDに関して発信したり、「質問箱」というサービスを通じて質問を受け付けています。こちらもよろしければフォローしてください。

[@little_hand_s](https://twitter.com/little_hand_s)

また、YouTubeで[10分でわかるDDD動画](https://www.youtube.com/playlist?list=PLXMIJq1G-_66F9woQpidJfe4HHCFxdXaA)シリーズをアップしています。概要を動画で理解したい方はこちらもどうぞ。チャンネル登録すると新しい動画の通知を受け取ることができます