【サルが書く】DDDで使われがちのアーキテクチャを紹介しよう！

うっきょい

DDDで実際に使われがちなアーキテクチャの話をしよう。

この記事では

- **ヘキサゴナルアーキテクチャ**
- **レイヤーアーキテクチャとの違い**
- **SOA（Service Oriented Architecture：サービス指向アーキテクチャ）**
- **REST**

についての話をします！

# DDDのアーキテクチャ

IDDDではヘキサゴナルアーキテクチャを提唱しています。

またヘキサゴナルアーキテクチャに関連が深い「サービス指向」「コマンドクエリ責務分離（CQRS）」「イベント駆動アーキテクチャ」といった概念やアーキテクチャ方式についても取り上げています。

また、DDDは特定のアーキテクチャ依存しません。
アーキテクチャの選定に関しては、「機能要求」「品質要求」が大きな判断材料になります。

## IDDD本のサンプルプロジェクトSaaSOvationでのアーキテクチャ変遷

IDDD本のサンプルプロジェクトSaaSOvationでは

1. レイヤアーキテクチャ
2. DIPに基づいたレイヤアーキテクチャ
3. ヘキサゴナルアーキテクチャ

の変遷が挙げられます。

## レイヤーアーキテクチャとは
いくつかの層にシステムを分割するアーキテクチャです。
このアーキテクチャのポイントはライブラリや名前空間を分割することに加え、各レイヤの依存関係を明確にして、敵セルな責務に沿って実装することが重要になります。

### レイヤーアーキテクチャとDDDを組み合わせた場合
- UI層
ドメイン層のモデルを使うことも可能だが、描画での使用のみが推奨されています。可能であれば、ドメインがビューの影響を受けないようにプレゼンテーションモデルを作ります。

- アプリケーション層
UI層から使用されます。
ここにはアプリケーションサービスが存在します。
アプリケーション層はドメイン層と異なり、ドメインロジックを持たない軽量なコーディネーターのような役割を果たします。
コーディネーターは、クライアント・アプリケーションと、要求されたデータを所有するノード間で、代理人としての役目を果たします

- ドメイン層
ユースケースやユーザーストーリーを実装します。ドメインモデルが提供され、「ファクトリ」か「集約」のコンストラクタにてインスタンスを生成します。ドメイン層には「ドメインサービス」が含まれ、ステートレスな操作として、ドメインの操作を行います。また、イベント駆動の場合「ドメインイベント」を発行します。

- インフラストラクチャ層
リポジトリを使用して、永続化を行います。

## 依存性逆転の原則（DIP）を用いたレイヤアーキテクチャ
依存性逆転の原則とは「上位が下位に依存する従来の形をやめて、抽象が詳細に依存するのではなく、実装が抽象に依存するべき」という指針です。

プログラムの実装としては、依存性の注入(DIコンテナ)、サービスファクトリ、プラグインなどの方式があります。

インフラストラクチャの実装にドメインが 依存するのではなく、ドメインの抽象に対してインフラストラクチャが依存する形になります。

このアーキテクチャになることによって、ドメインが他のレイヤーに依存することがなくなったため、ドメイン層が、独立して管理がしやすくなります。

## ヘキサゴナルアーキテクチャ
DIPの導入でドメインの独立性は高くなったものの、インフラストラクチャ層の実装は複雑になりがちです。
そこでヘキサゴナルアーキテクチャを導入しました。

ヘキサゴナルアーキテクチャとは、ドメイン層を中心に捉えて、ユーザー操作、自動テストといった入力側もデータベース、モックといった出力側も、全てまとめて差し替え可能な外部のインターフェースとして扱うといったアーキテクチャです。

レイヤーアーキテクチャでは上位と下位(フロントからバックエンドの流れ)という関係性でありましたが、ヘキサゴナルアーキテクチャではドメインを中心にし、処理を発火させるプライマリと処理を発火させられるセカンダリと連携をします。

プライマリ側からドメインが呼び出されて、セカンダリ側で保存処理を行ったりと対象性を想起させるアーキテクチャになっています。

### ヘキサゴナルを構成する「ポート＆アダプタ」
ヘキサゴナルアーキテクチャは構造上から「ポート＆アダプタ」とも言われています。プライマリとセカンダリがアダプタとなり、それぞれを受け付ける形でポートが設計される。

アダプタは技術的に差し替えが可能になってるものです。

ドメイン部分は機能やユースケースをもとに設計し、ポート＆アダプタの部分は技術的なあインターフェース別で設計するイメージです。

### ヘキサゴナルアーキテクチャのメリット
柔軟なアーキテクチャのため、ほかのアーキテクチャもうまく取り入れられる。

また周辺の技術が決まってなくても、とりあえずアダプタを作成することで、ドメインの開発が進められる。


## ヘキサゴナルでのサービス指向のアプローチ
### SOA（Service Oriented Architecture：サービス指向アーキテクチャ）の導入

SOAはサービス指向アーキテクチャのことです。
ソフトウェアをサービスとして連携させ、システム全体を構築していきます。

|No.|原則|説明|
|---|---|---|
|1.|標準化|サービスの説明を契約（インターフェース）で示す。|
|2.|疎結合性|依存関係を最小限にし、依存するものだけ認識する。|
|3.|抽象性|自身の契約（インターフェース）だけを公開し、内部実装は公開しない。|
|4.|再利用性|他のサービスからも再利用可能。|
|5.|自立性|一貫性と信頼性を持ち、独立して成り立つ。|
|6.|ステートレス性|利用者側で状態を管理する。|
|7.|発見可能性|メタデータを記述して、他から発見可能にする。|
|8.|構成可能性|大きいサービスに組み込み可能で、大きさや複雑度に制限がない。|

この項目をDDDに当てはめることで、ユビキタス言語や、境界づけられたコンテキストを不自然に分担していないかを確認することができる。

## ヘキサゴナルで使用されるREST
DDDでWebサービスを構築する時によく利用される技術がRESTです。

### RESTの特徴
- リソースを一意なURIで識別可能
RESTではURIによる一意なアドレスを持ち、そのURIで提供するリソースを識別できる。

- ステートレスな通信
クライアントとサーバー感の通信はステートレスに行われます。
RESTfullなHTTPサーバーは前回のリクエスト状態を記憶しないため、買う通信に処理のための必要な情報がすべて含まれる。

- GET／POST等の命令指針に基づいたリソース操作
GET等のHTTPメソッドを使用してリソースを操作する。
HTTPメソッドが振る舞いを表してくれるので、URLに動詞を含めることなく、名詞主体のわかりやすいURLを構成できる。

- 関連リソースへのナビゲーションを扱う「ハイパーメディア」
RESTの中ではハイパーメディアを用いて、レスポンスの中に他のリソース情報を埋め込むことができる。

### DDDでのRESTの使用
RESTは、疎結合で利用がしやすい仕組みのためスケーラブルなサービスの提供にも適しています。これはヘキサゴナルアーキテクチャに通ずるところがあり、相性が良いとされています。



## まとめ
DDDのアーキテクチャの変遷や使われている技術について簡単にまとめました。
この記事が参考になれば幸いです！

※「コマンドクエリ責務分離（CQRS）」「イベント駆動アーキテクチャ」についてはかなりボリュームがあるので、別途まとめていきます！

## 参考
https://codezine.jp/article/detail/9922

https://qiita.com/takasp/items/f05ef45a6fadd916ffa8