はじめてのDDD part4.1 ~DIP、ヘキサゴナルアーキテクチャとは?~

# はじめに
前回のpart4に引き続きアーキテクチャの解説をしていきます。今回はタイトルでもあるように、「DIP」、「ヘキサゴナルアーキテクチャ」について紹介します。なお、「ヘキサゴナルアーキテクチャ」については少しボリュームがあるので、次回より深く解説しようと思います。
では、さっそく始めていきます！

# DIP（依存関係逆転の原則）を用いたレイヤ化アーキテクチャとは
DIPとは、「Dependency Inversion Principle」の略で、これをそのまま日本語に訳したものが「依存関係逆転の原則」となります。
概要を紹介すると、<strong>「今までのように上位が下位に依存することをやめて、関係を逆転させよう」</strong>というものです。<strong>「抽象は、実装の詳細に依存すべきではない。実装の詳細が、抽象に依存すべき」</strong>ともいえます。
下の画像が概念図を表しています。
![スクリーンショット 2024-10-30 132716.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817741/60af9f97-9cd1-134a-92e6-2a306a779bed.png)
名前の通り上下関係が逆転していることがわかります。
このアーキテクチャでは、ドメインが他のレイヤに依存しなくなるので、ドメイン層を独立させ、シンプルに管理しやすくなります。
さて、一応紹介してみたもの、依然としてイメージが難しいと思うのでここからはもっとかみ砕いて説明しようと思います。

まず前提知識として、表示を担当する「プレゼンテーション層」を設けた場合、それは「UI層」などの変更によりコードを書き換えなければならないことがありがちだということを頭に入れておいてください。
つまり、<strong>「プレゼンテーション層」は安定性が低く、柔軟性が求められるということ</strong>です。一方で、「ドメイン層」はルールや制約（システムの本質）を定義するため、柔軟性が求められることはほぼありません。例として、じゃんけんのゲームを開発する際、「パーはグーに負ける」というような絶対的なルールは変更できないでしょう。


ここで、先ほど紹介した概要を振り返ってみましょう。DIPにおいて、上位（抽象）を「UI層」、下位（実装）を「ドメイン層」とすると、「ドメイン層」は「UI層」に依存する形なります。

:::note info
依存関係が成立する場合、依存<strong>する</strong>側は安定性が低く、柔軟性が高くなりがちである。これは、仮にモジュールのimportを考えると、依存する側のコードはより複雑になる（理解が難しくなる）からです。
:::
このことを踏まえると、DIPの具体例として、「ドメイン層」で「UI層」のモジュールをimportするのはやめよう、ということが挙げられます。


# ヘキサゴナルアーキテクチャについて

:::note warn
「はじめに」で述べた通り、今回はヘキサゴナルアーキテクチャの概要だけ紹介します。
:::
先ほど紹介したDIPを採用することでドメインの独立性は高まりました。しかし同時に、「インフラストラクチャ層」（DIP採用時に一番上位に位置づけられるもの）の実装は複雑になってしまします。そこで、その問題を解決するために考え出されたのがこの「ヘキサゴナルアーキテクチャ」です。まず簡単にイメージを表した以下の画像に軽く目を通してください。
![entry_img_20161109.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817741/d3b78e5c-6234-8c35-78b8-10f59c8d8037.png)

ヘキサゴナルアーキテクチャにおいて押さえておきたいポイントは以下の3つです。
<ol>
<li>ビジネスロジックが中心である
<li>ユーザー操作などの入力側、データベースなどの出力側のどちらも差し替え可能である
<li>部品を自由に入れ替えられる
</ol>
前回紹介したレイヤ化アーキテクチャでは、上位（またはフロントエンド）と下位（またはバックエンド）という<strong>非対称的な</strong>構成でした。

:::note warn
ここでいう「非対称的」とは、データや操作の流れが一方的（一方的に依存する関係）であるということである。
:::

しかし、ヘキサゴナルアーキテクチャでは、上の画像であるように、「ドメイン」を中心において「処理をするプライマリ（Primary）側」、「処理が駆動されるセカンダリ（Secondary）側」と連携します。具体的に説明すると、プライマリ側は主となる入力（ドメイン層）を呼び出す役割を、セカンダリ側は
ドメインが外部に処理結果を出力したり、データの保存などをしたりします。

### ポート＆アダプター
ヘキサゴナルアーキテクチャはそのつくりの仕組みから、「ポート＆アダプター」とも呼ばれます。「ポート」はシステムの目的に応じて設計され、前述したような差し替え可能部分は「アダプター」として用意されます。上の画像と同じことを説明することになりますが、「ドメイン」部分はユースケースをもとに設計し、「ポート＆アダプタ部分」は技術的なインターフェイス（通信や記録など）をそれぞれで設計するイメージとなります。

### メリット
さて、ヘキサゴナルアーキテクチャについて長々と説明しました。「結局何がうれしいのか」を説明して今回の記事は終わりにします。
ヘキサゴナルアーキテクチャはその仕組みから、柔軟なアーキテクチャであることは理解できたと思います。<strong>柔軟なアーキテクチャの良いところは他のアーキテクチャもうまく取り込めることです。</strong>加えて、周辺の技術が決まっていなくても、暫定的に「アダプター」を作成し、ドメインの開発を進めることができます。
さらにうまく設計すると、ドメイン層のロジックを完結させることでユースケースを適切に実装できます。

# おわりに
今回はDDDとヘキサゴナルアーキテクチャの概要を紹介しました。はじめに書いた通り、ヘキサゴナルアーキテクチャではもう少し追加で触れておきたい部分があるのでそこを次回は紹介します。
では、最後までお読みいただきありがとうございました。次回もよろしくお願いします。


### 参考
[「実践ドメイン駆動設計」から学ぶDDDの実装入門/青木 淳夫](https://www.amazon.co.jp/%E3%80%8C%E5%AE%9F%E8%B7%B5%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88%E3%80%8D%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6DDD%E3%81%AE%E5%AE%9F%E8%A3%85%E5%85%A5%E9%96%80-CodeZine-Digital-First-%E9%9D%92%E6%9C%A8/dp/4798161500/ref=tmm_hrd_swatch_0?_encoding=UTF8&sr=8-1)

[実践DDD本 第4章「アーキテクチャ」 ～レイヤからヘキサゴナルへ～](https://codezine.jp/article/detail/9922)
[【SOLID原則】依存性逆転の原則 - DIP](https://zenn.dev/chida/articles/e46a66cd9d89d1)
[ドメインモデル中心のアーキテクチャ](https://devtab.jp/entry/internal/42)