クリーンアーキテクチャ@アーキテクチャ¶
はじめに¶
本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。
01. アーキテクチャ概要¶
思想¶
ドメイン駆動設計が適する機能的アプリケーションのみでなく、あらゆる種類 (例:非機能的アプリケーションなど) のソフトウェアに適用できる。
クリーンアーキテクチャ原著の序文にて、著者は「私は今まで色々な種類のシステムを作ってきたが、どのシステムでもアーキテクチャのルールは同じだった」と述べている。
異なるシステムでも同じルールを共有する必要がある』というようなことを述べている。
構成¶

各パターンの分類¶
オブジェクト指向型と手続き型のマルチパラダイム言語の場合、アプリケーションをクラスまたは関数で実装できる。
クリーンアーキテクチャはオブジェクト指向設計が前提にあるため、各レイヤーのパターンをクラスとして実装することが多い。
ただし、クラスとして実装するとインスタンス化の手間がある。関数として実装しても、アーキテクチャの思想に反しない場合がある (特に外側のレイヤー) 。
アーキテクチャのレイヤー別にこれを整理した。
| バックエンドレイヤー | パターン | 責務 | インターフェース/実装 |
|---|---|---|---|
| インフラストラクチャ層 | DB | データベースとの接続、コネクションの作成 | 実装 |
| EntityMappers (DTOに相当) | ドメインとインフラ間のオブジェクトの詰め替え | 実装 | |
| Logger | ロギング | 実装 | |
| Middleware | ミドルウェアパターン | 実装 | |
| Repositories | 実装リポジトリ | 実装 | |
| Listeners | リスナー | 関数 | |
| Routers | ルーティング | 関数 | |
| Seeder | 開発環境、CI環境のユニットテストやE2Eテスト、ステージング環境の動作確認に使用する初期データ挿入 | 実装 | |
| Drivers | SDK、ORM、CLIなど | 実装 | |
| プレゼンテーション層 | Controller | データの受信と返信 | 実装 |
| RequestValidators | 受信データのバリデーション | 実装 | |
| ResponseValidators | 返信データのバリデーション (受信データと比べてデータ構造は保証されているため、なくてもいい) | 実装 | |
| Authenticators | 認証 | 実装 | |
| InputAdapter | 型変換、入力データ翻訳、フロントエンドインターフェース (あるいは受信JSONデータ) からバックエンドインターフェースへのオブジェクトからへの詰め替え | 実装 | |
| OutputAdapter | 型変換、出力データ翻訳、バックエンドインターフェースからフロントエンドインターフェースへのオブジェクトからへの詰め替え | 実装 | |
| ユースケース層 | Interactor | ドメイン層で定義されたビジネスルールを組み合わせ、ユースケースを具現化する。 | 実装 |
| InputBoundaries | Interactorのインターフェース | インターフェース | |
| InputDTOs (DTOに相当) | 型変換、バックエンドインターフェースからユースケースのオブジェクトからへの詰め替え | 実装 | |
| OutputBoundaries | Presenterのインターフェース | インターフェース | |
| OutputDTOs (DTOに相当) | 型変換、ユースケースからフロントエンドインターフェースへのオブジェクトからへの詰め替え | 実装 | |
| Repositories(Gatewaysとも呼ぶ) | Repositoriesのインターフェース | インターフェース | |
| ドメイン層 | Entity | ドメインモデル、ビジネスルールの定義 | 実装 |
| Id | ドメインモデルの識別子 | 実装 | |
| ValueObject | 値オブジェクト | 実装 | |
| Specification | ビジネスロジックのバリデーション | 実装 | |
| Criterion | 検索条件オブジェクト | 実装 | |
| Events | ドメインイベント | 実装 | |
| Service | ドメインサービス | 実装 |
| フロントエンドレイヤー | パターン | 責務 | インターフェース/実装 |
|---|---|---|---|
| プレゼンテーション層 | Presenter | ドメインオブジェクトからJSONデータへの詰め替え | 実装 |
| Validators | フロントエンドのバリデーション | 実装 | |
| ViewModel | 状態管理、JSONデータをフロントエンドインターフェースのオブジェクトへの詰め替え | 実装 | |
| UI層 | View | UIレンダリング、CSSスタイリング | 実装 |
実装例たち¶
| 言語 | あれば書籍名 | URL |
|---|---|---|
| TypeScript | つくりながら学ぶ! ドメイン駆動設計 実践入門 | https://github.com/yamachan0625/hands-on-ddd-introduction/tree/main/chapter-21 |
| Java | なし | https://github.com/VaughnVernon/IDDD_Samples |
| Go | なし | https://github.com/victorsteven/food-app-server |
| C# | ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本 | https://github.com/nrslib/itddd |
| そのほか | なし | https://github.com/stars/hiroki-it/lists/ddd-architecture |
02. アーキテクチャにおけるレイヤー別の例外スロー¶
スローされた例外の扱い¶
各レイヤーでは例外をスローするだけに留まり、スローされた例外を対処する責務は、より上位レイヤーに持たせる。
より上位レイヤーでは、そのレイヤーに合った例外へ詰め替えてスローする。
最終的には、インターフェース層まで持ち上げ、画面上のポップアップで警告文としてこれを表示する。
インターフェース層¶
▼ 例外クラス¶
final class プレゼンテーション層Exception extends Exception
{
}
▼ 例外の種類¶
| 例外名の例 | 説明 |
|---|---|
BadRequestError |
リクエスト形式が不正 |
UnauthorizedError |
認証されていない |
ForbiddenError |
認可されていない |
▼ ハンドリング¶
ユースケース層の処理をtry-catchで囲い、スローされたユースケース例外をエラーレスポンスにして返信する。
ユースケース層¶
▼ 例外クラス¶
final class InteractorException extends Exception
{
}
▼ 例外の種類¶
ユースケースの処理に失敗した例外である。
| 例外名の例 | 説明 |
|---|---|
FooNotFoundError |
Fooドメインオブジェクトが存在しない |
FooAlreadyExistsError |
Fooドメインオブジェクトが重複する |
FooQuotaExceededError |
Fooドメインオブジェクトの登録上限を超えている |
FooChangeFailedError |
更新系ユースケースが失敗した |
FooRegisterFailedError |
登録系ユースケースが失敗した |
FooGetFailedError |
閲覧系ユースケースが失敗した |
FooDeleteFailedError |
削除系ユースケースが失敗した |
▼ ハンドリング¶
ドメイン層の処理をtry-catchで囲い、スローされたドメイン例外をユースケース例外にして返却する。
ドメイン層¶
▼ 例外クラス¶
final class DomainException extends Exception
{
}
▼ 例外の種類¶
ビジネスルールに違反した例外である。
| 例外名の例 | 説明 |
|---|---|
InvalidFooNameError |
Foo 名がドメインルールに違反している |
インフラストラクチャ層¶
▼ 例外クラス¶
final class インフラストラクチャ層Exception extends Exception
{
}
▼ 例外の種類¶
データベースに関する例外である。
| 例外名の例 | 説明 |
|---|---|
UniqueConstraintError |
プライマリーキー違反 |
ForeignKeyConstraintError |
外部キー制約違反 |
DatabaseConnectionError |
DB接続失敗 |
QueryTimeoutError |
クエリがタイムアウトした |
▼ ハンドリング¶
トランザクションの処理をtry-catchで囲い、スローされたインフラストラクチャ例外をドメイン例外にして返却する。