コンテンツにスキップ

クリーンアーキテクチャ@アーキテクチャ

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. アーキテクチャ概要

思想

ドメイン駆動設計が適する機能的アプリケーションのみでなく、あらゆる種類 (例:非機能的アプリケーションなど) のソフトウェアに適用できる。

クリーンアーキテクチャ原著の序文にて、著者は「私は今まで色々な種類のシステムを作ってきたが、どのシステムでもアーキテクチャのルールは同じだった」と述べている。

異なるシステムでも同じルールを共有する必要がある』というようなことを述べている。


構成

clean-architecture

各パターンの分類

オブジェクト指向型と手続き型のマルチパラダイム言語の場合、アプリケーションをクラスまたは関数で実装できる。

クリーンアーキテクチャはオブジェクト指向設計が前提にあるため、各レイヤーのパターンをクラスとして実装することが多い。

ただし、クラスとして実装するとインスタンス化の手間がある。関数として実装しても、アーキテクチャの思想に反しない場合がある (特に外側のレイヤー) 。

アーキテクチャのレイヤー別にこれを整理した。

バックエンドレイヤー パターン 責務 インターフェース/実装
インフラストラクチャ層 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で囲い、スローされたインフラストラクチャ例外をドメイン例外にして返却する。