本記事の内容
Go言語によるWebアプリの個人開発に挑戦中の非Web系エンジニアが、個人の勉強の過程で情報を整理するための自分向けページ。
調べる中で出てきた別ページの情報を1か所にまとめるために使用。
この記事を見て読者であるあなたが何か学べる、という内容ではありません、、、
クリーンアーキテクチャの目的
設計思想
- 依存性逆転の原則(Dependency Inversion Principle): 高レベルのモジュールは低レベルのモジュールに依存すべきではなく、どちらも抽象に依存すべき。抽象は詳細に依存してはならない。
- 単一責任の原則(Single Responsibility Principle): 一つのクラスはただ一つの責務を持つべきであり、変更の理由は一つであるべき。
メリット/デメリット
- 保守性向上: フレームワーク非依存で変更が容易。バグが発生しにくい構造を提供
- テストが容易性: 機能を分割しドメインを区切ることでテスト、統合テストがしやすい
- 拡張性: 別のドメインとの間にインターフェースを介することにより、内部の修正を外部に漏らさない。新しい機能や変更が容易に組み込める構造を確立
- 機能の分断、別ロジックとはインターフェースを介すためコードが冗長になる
本題
ここから自分の理解を整理する内容です。
クリーンアーキテクチャの図
DDDアーキテクチャ詳細像
DDDアーキテクチャとクリーンアーキテクチャ図のマッピング
-
Presentation層(Controller)
- エンドポイント定義
- Http requestで渡された値とApplication層に渡す値のマッピング
- 入力値のvalidation(一部)
- クリーンアーキテクチャの
Frameworks & Drivers
に対応- WebサーバーからのリクエストやUIでの操作を吸収。
- 処理の結果を返す
- 外部との境界(バウンダリ)
-
Interface層(Repositry(実装クラス))
- Entityの永続化/検索
- クリーンアーキテクチャの
Interface Adapters
に対応- データの取得や永続化を担当
- Interfaceなので、機能の外側だけを定義(例えばデータの追加、検索など)
- 中の実装はDomein層で書く。公開部分を変更しなければ内部処理が変わっても外部に影響は及ばない
-
Use Case層(Application層)
- ユースケースの実現
- Entity、Value、Objectの生成、使用、永続化 依頼
- EntityからPresentation層に渡す値への変換
- クリーンアーキテクチャの
Application Business Rules
に対応- アプリケーション固有のビジネスルール、DDDにおけるアプリケーションサービスなどを定義します。
- ここに実現したい処理を書く
-
Domain層(Repositry)
- Repositryの仕様定義
- ドメイン知識(ルール/制約)の表現
- Entity、Value、Object、Domain Serviceなど
- クリーンアーキテクチャの
Enterprise Business Rules
に対応- 最重要ビジネスルール、DDDにおける値オブジェクト、エンティティ、ドメインサービスなどを定義
usecaseを中心としたクラス図で表現してみる
- Use CaseはDomainに依存する
- Use Caseはアプリケーションで実現したいビジネスロジック
- Domainはビジネスロジックを構成(表現)するルールやデータ構造
- Use CaseはRepositoryインターフェースに依存する
- インターフェースは提供する機能の「側」だけを提供(関数とその入出力の側しか知らなくてよい)
- 側さえ守ればインターフェースの実態の実装はどのように変化させても良い
- インターフェースは提供する機能の「側」だけを提供(関数とその入出力の側しか知らなくてよい)
- Use Caseを扱うcontrollerにはUse Caseインターフェースを提供。
- こちらもUse Caseの実態の実装はインターフェースで定義した側を守っていれば
- どのように実装しても構わない
このようにインターフェースを介することで依存の逆転を実現している
UMLに準拠したクラス図での表現
- Use Caseはインターフェースで定義した内容に準拠したmethodを実装
- modelsや振る舞いのデータ授受に必要な機能はRepositoryインターフェースを介して実行