DDDとは結局何なのか 軽量DDD 2

# 前回
- [こちら](https://qiita.com/takassh/items/8f3accce91f6ad481e49)
- DDDの考えというものを説明しました。
- 軽量DDDとは何なのかについて説明しました。

# 今回
- 複数のアーキテクチャを比較して、軽量DDDを実現するためにはどうすれば良いのか話していきます。
- 今回の内容は軽量DDDというものになりますので、軽量DDDとDDDの違いが分からない方は[こちら](https://qiita.com/takassh/items/8f3accce91f6ad481e49)をみるべきと思います。

# 参考
- DDDがパターンを紹介しているにすぎないことが書いてあります　[リンク](https://www.ogis-ri.co.jp/otc/hiroba/technical/DDDEssence/chap1.html)
- さらに細かくDDDについて触れています [リンク](https://little-hands.hatenablog.com/archive/category/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88%28DDD%29)

# Layered Architecture

![layer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372622/2ea3471b-f1b9-88cc-9fee-35d0f45f02ac.png)

これはDDDの中で紹介されたアーキテクチャです。これからのアーキテクチャを説明する上で重要な要素があります。
- 各層の用語の意味
- 依存関係がはっきりと決まっている
順番に説明していきます。

### **各層の用語の意味**

- UI層
    - ユーザーから見える部分のコードを担当する層(例えばマークアップ言語は完全にここな気がする)
- Application層
    - データを加工してUI層が扱いやすくするための層。例えば、created_atにunixtimeで時刻が保存されているとしても、そのままの表示をすることは少ない。そのためにここの層で月日だけを取り出してUI層に渡す。
- Domain層
    - ビジネスロジックが含まれる層のことで、ここでドメイン解決のためのコードが書かれます。
- Infrastructure層
    - データとのやりとりを担当する層。保存したり取得したりする。
 
個人的には**Application層には他のアプリでも流用できるような、汎用性の高いコード**がくるんじゃないかと思います。例えば時刻変換といった作業は他のアプリでも使うことができますよね。それとは対照的に**ドメイン層とは、そのプロダクトオリジナルのコード**がここにくるんじゃないかと思います。だからもし、時刻変換で少し複雑そうなことをした場合はドメイン層に置くのが正解の時もあると思います。

### **依存関係がはっきりと決まっている**

「依存関係は上の層から下の層のみ許可する」とは、Domain層からApplication層のメソッドや関数を呼ぶといったことが**無いようにする**と言うことです。なぜこのようにするのかと言うと、[前回](https://qiita.com/takassh/items/8f3accce91f6ad481e49#ddd%E3%81%A8%E3%81%AF%E7%B5%90%E5%B1%80%E4%BD%95%E3%81%AA%E3%81%AE%E3%81%8B)お話しした1番や3番を達成するためです。**DDDとはドメインを元にアジャイルにプロダクトを更新していくもの**ですから、若干の方針変更によるApplication層の更新はドメインに影響させたくない訳です。また**プログラマーを層ごとに分けて効率よく開発していきたいのに、層がめちゃくちゃな依存関係だと、アプリが出来上がりませんし、テストも切り分けて行いにくい**です。

さて、*このモデルはDDDを忠実に再現できているでしょうか*?
答えは、まだ改善の余地ありです。理由としては、**DDDはドメインが中心の世界であるはずなのにインフラ層に依存してしまっていますね**。また、**ドメイン層の役割が大きすぎる**ように思います。
ただし、**層分けしたこと**と、**依存関係をはっきりさせたこと**にとても意味があったという事実を忘れないでください。

# Hexagonal architecture

![へきさ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372622/7ae5968f-8584-8805-e7b2-08162cb9edfe.png)

これは見ただけではあまり意味が分からないと思います。ただし、**層分けしたこと**と、**依存関係をはっきりさせたこと**を引き継いでいることに留意してください。ポイントは2つあります。

- ドメインを依存の中心に置いている
- 図が抽象化されている

順番に説明していきます。

### ドメインを依存の中心に置いている
先ほどのLayered Architectureでは結局インフラが中心となってしまっていて、データベースの種類や、フレームワークなどにドメインが依存する形となってしまっていました。それを改善したのがこの図となっています。ただしデータの取得方法に依存しないコードの書き方というのは少し想像がしにくいです。ここの解決方法は[次回の記事]()にしたいと思います。(<=更新したらリンクが貼られているはず)

### 図が抽象化されている
層に名前が付いていますが、Domain ModelとApplicationとそれ以外の3つしかありません。これはどういうことなのかというと、最低限この3つを満たしてアーキテクチャを構成しようということで、ひたすら**ドメインを中心に置くべき!と主張しているに過ぎない**です。これを雛形としてクリーンアーキテクチャやオニオンアーキテクチャが存在しています。これでは抽象化され過ぎているということで、次はオニオンアーキテクチャを見てみましょう。

# Onion architecture

![onion_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372622/6bb61bd3-1135-4109-6e7e-181eb8231ed6.png)

やっとここまできました。これまでの考え方を全て引き継いでいることに留意してください。**層分けしたこと**と、**依存関係をはっきりさせたこと**と**ドメインを依存の中心に置いている**こと**抽象化された概念を引き継いでいること**この4つです。
ここでのポイントは2つあります。

- Domain層が2つに分かれた
- 具体化した

### Domain層が2つに分かれた
一番最初の**Layered Architectureはなんだかんだ言ってDomain層の役割が大き過ぎました**。例えば、データのモデルを定義するのもDomain層でしたし、ビジネスロジックを実装するのもそこでした。これを切り分けるためにDomain層をModelとServiceに分けてあげたというのがこのアーキテクチャです。

### 具体化した
ヘキサゴナルアーキテクチャと比べて、図が具体化したと思います。つまり、ヘキサゴナルアーキテクチャとオニオンアーキテクチャまたはクリーンアーキテクチャは本質的には同じことを表していて、その表現方法がそれぞれ違ったというだけなのです。本質的な**ドメインを依存の中心に置く**という考えは変わっていません。

# まとめ
- 複数のアーキテクチャを比較し、それぞれがどのような主張をしているのか話した
- **層分けしたこと**、**依存関係をはっきりさせたこと**、**ドメインを依存の中心に置いていること**(Layered Architectureはまだ甘かったがその意思は感じる)がこれらのアーキテクチャで共通していることを話した

# 次回
- これらのアーキテクチャでどうやってインフラに依存しないドメインを形成するのかについてコードを交えて話したいと思います。[次回の記事]()(<=更新したらリンクが貼られているはず)