メインコンテンツまでスキップ

ユースケースとビジネスロジック

読了時間: 約15分

はじめに

Prism Architectureの重要な側面の一つは、特にそのオーケストレーション層を通じてビジネスロジックをどのように編成し構造化するかです。この文書では、Prism Architectureにおけるユースケースとビジネスロジックの階層的アプローチを探り、アーキテクチャがアプリケーション機能を編成するための明確な構造を提供しながら、関心の分離をどのように維持するかを説明します。

アプリケーション全体にビジネスロジックを様々な場所に配置する可能性のあるよりシンプルなアーキテクチャとは異なり、Prism Architectureは明確な境界と責任を持つ構造化されたアプローチを作成します。この編成は保守性を向上させるだけでなく、テスト容易性を高め、変化する要件に対してシステムをより適応させやすくします。

ビジネスロジックの配置

ドメイン vs. オーケストレーションロジック

Prism Architectureは2種類のビジネスロジックを明確に区別します:

  1. ドメインロジック: ビジネスドメインの核心的な知識を表す純粋なビジネスルール、バリデーション、計算
  2. オーケストレーションロジック: システムの異なる部分にまたがる操作の調整とシーケンス

これら2種類のロジックはPrism Architectureで意図的に分離されています:

  • ドメインロジックはドメイン層に存在し、通常はドメインサービスとエンティティ内にある
  • オーケストレーションロジックはオーケストレーション層に存在し、ユースケース、オーケストレーションサービス、ワークフロー内にある

この分離により、ドメインの専門家はビジネスルールを正確に捉えることに集中でき、アプリケーション開発者は関心事を混在させることなく操作の流れの実装に集中できます。

階層的オーケストレーション構造

Prism Architectureの主要な革新の一つは、オーケストレーションコンポーネントへの階層的アプローチです。すべてのユースケースを平等に扱うのではなく、Prismは徐々に拡大する能力とスコープを持つ明確な階層を定義します。

この階層は、それぞれ特定の責任と境界を持つ3つのレベルのコンポーネントで構成されています:

  1. ユースケース: エンティティ重視のアトミックな操作
  2. オーケストレーションサービス: 機能/集約レベルの調整
  3. ワークフロー: ドメイン横断プロセス

それぞれのレベルを詳しく見ていきましょう。

ユースケース

定義と特徴

Prism Architectureにおけるユースケースは、集約内の単一のエンティティに焦点を当てた、明確に定義された特定の操作を実装します。それらは明確で狭い焦点を持つアトミックなビジネス操作を表します。

ユースケースの主な特徴には以下が含まれます:

  • 単一エンティティ重視: 各ユースケースは集約内の単一のエンティティを扱う
  • アトミックな操作: 特定の分割できない操作を処理する
  • 明確な命名: 動詞-名詞の組み合わせで命名される(例:RegisterUserUseCase
  • 調整役: ドメイン、インフラストラクチャ、プレゼンテーション層の間を調整する
  • 最小限のロジック: 調整以外の最小限のロジックを含む

境界と制約

ユースケースは厳格な境界内で動作します:

  • 集約内の単一のエンティティに対する操作に限定される
  • 他のユースケースを呼び出すことができない
  • ビジネスロジックにはドメインサービスを使用できる
  • 外部操作にはインフラストラクチャサービスを使用できる

これらの制約により、ユースケースは一度に1つの特定の操作のみを処理し、焦点を絞って保守性を維持できます。

一般的なユースケースパターン

ユースケースの典型的なパターンには以下が含まれます:

  1. CRUD操作: エンティティのCreate、Read、Update、Delete操作
  2. 状態遷移: エンティティを定義された状態変化を通じて移行させる
  3. バリデーションと処理: 入力を検証し、特定の操作を実行する
  4. シンプルなクエリ: 特定のユースケースのためのデータ取得

ユースケースの例

明確に定義されたユースケースの例には以下が含まれます:

  • RegisterUserUseCase: ユーザー登録を処理する
  • UpdateProductDetailsUseCase: 商品情報を更新する
  • PlaceOrderUseCase: 注文の処理を行う
  • CancelSubscriptionUseCase: サブスクリプションのキャンセルを処理する

オーケストレーションサービス

定義と特徴

オーケストレーションサービスは、特定の機能領域または集約内の関連する操作を管理します。複数のユースケースを構成できますが、同じ機能境界内に限られます。

オーケストレーションサービスの主な特徴には以下が含まれます:

  • 機能領域重視: 各サービスは一貫性のある機能領域を管理する
  • 構成能力: 機能内の複数のユースケースを構成できる
  • 命名規則: 機能ドメインに基づいて命名される(例:AuthenticationOrcService
  • 状態管理: 機能固有の状態やコンテキストを維持する場合がある
  • 機能API: 関連する操作のための一貫性のあるAPIを提供する

境界と制約

オーケストレーションサービスは定義された境界内で動作します:

  • 単一の機能ドメインまたは集約内の操作に限定される
  • 複数のユースケースを構成および呼び出すことができる
  • 異なるドメインのオーケストレーションサービスを呼び出したり依存したりできない
  • コンポーネント階層の中間層として機能する

これらの制約により、オーケストレーションサービスは個々のユースケースよりも複雑な操作を調整できるようになりながら、明確な機能ベースの一貫性を維持できます。

一般的なオーケストレーションパターン

オーケストレーションサービスの典型的なパターンには以下が含まれます:

  1. 機能構成: 複数のユースケースを機能ワークフローに結合する
  2. 状態管理: 複数の関連操作間でコンテキストを維持する
  3. トランザクション管理: 複数の操作間で一貫性を確保する
  4. 機能レベルのバリデーション: 関連エンティティ間の複雑な制約を検証する

オーケストレーションサービスの例

明確に定義されたオーケストレーションサービスの例には以下が含まれます:

  • AuthenticationOrcService: 認証関連の操作を管理する
  • OrderManagementOrcService: 様々な注文関連の操作を調整する
  • SubscriptionOrcService: サブスクリプション関連の機能を処理する
  • ProfileManagementOrcService: ユーザープロフィール関連の操作を管理する

ワークフローコーディネーター

定義と特徴

ワークフローコーディネーターは、複数の機能領域と集約を含む可能性のある複雑な多段階プロセスを管理します。異なるドメインからのユースケースとサービスの両方を構成できます。

ワークフローコーディネーターの主な特徴には以下が含まれます:

  • ドメイン横断スコープ: 異なる集約とドメインにまたがって動作する
  • プロセス重視: エンドツーエンドのビジネスプロセスを処理する
  • 命名規則: プロセスに基づいて命名される(例:CheckoutWorkflow
  • 状態管理: プロセス全体の状態遷移を管理する
  • 複雑な調整: 複数の機能領域にまたがって調整する

境界と制約

ワークフローコーディネーターは階層の中で最も広いスコープを持ちます:

  • 複数の機能ドメインと集約にまたがって動作できる
  • ユースケースとオーケストレーションサービスの両方を構成できる
  • コンポーネント階層の最上位を表す
  • 複数のドメインにまたがる真に複雑なプロセスにのみ使用される

より広いスコープにもかかわらず、ワークフローは特定のビジネスプロセスに焦点を当て、全てを処理するコンポーネントになることを避けるべきです。

一般的なワークフローパターン

ワークフローコーディネーターの典型的なパターンには以下が含まれます:

  1. 多段階プロセス: 明確な段階を持つプロセスの管理
  2. ドメイン横断調整: ドメイン境界を越えたアクションの調整
  3. サガパターン: 複雑な操作のための補償トランザクションの管理
  4. ステートマシンの実装: 複雑な状態遷移の実装

ワークフローコーディネーターの例

明確に定義されたワークフローコーディネーターの例には以下が含まれます:

  • CheckoutWorkflow: 完全な決済プロセスを管理する
  • OnboardingWorkflow: 複数の機能にまたがるユーザーオンボーディングを調整する
  • PaymentProcessingWorkflow: エンドツーエンドの支払いプロセスを処理する
  • ContentPublishingWorkflow: コンテンツ作成と公開プロセスを管理する

ビジネスロジック実装パターン

ドメイン駆動ロジック

Prism Architectureは、ドメイン層で中核的なビジネスルールを実装することを強調しています:

  1. ドメインサービス: 単一のエンティティに属さないビジネスロジック用
  2. エンティティメソッド: エンティティ固有のビジネスルール用
  3. バリデーションサービス: 複雑なバリデーションルール用
  4. ドメインイベント: リアクティブビジネスプロセス用

このアプローチにより、中核的なビジネスルールが一元化され一貫性を保ちます。

ユースケース構造パターン

Prism Architectureにおける典型的なユースケースは次のパターンに従います:

  1. 入力バリデーション: 入力パラメータの検証
  2. 権限チェック: 操作が許可されているかの確認
  3. ドメインロジック委譲: 適切なドメインサービスの呼び出し
  4. インフラストラクチャ調整: リポジトリや他のサービスの使用
  5. 結果構成: 適切なレスポンスの作成

この一貫した構造により、ユースケースは予測可能で保守しやすくなります。

オーケストレーションサービス構成

オーケストレーションサービスは通常、いくつかのパターンの一つでユースケースを構成します:

  1. 順次構成: ユースケースを順番に実行する
  2. 条件分岐: 条件に基づいてユースケースを選択する
  3. 並列実行: 独立したユースケースを同時に実行する
  4. 集約: 複数のユースケースからの結果を組み合わせる

これらの構成パターンにより、機能の柔軟な調整が可能になります。

通信パターン

コマンドベース通信

Prism Architectureでは通常、オーケストレーション層との通信にコマンドオブジェクトを使用します:

  1. コマンドオブジェクト: 操作リクエストを表す不変オブジェクト
  2. 結果オブジェクト: 操作結果を含む構造化されたレスポンス
  3. バリデーション結果: バリデーション結果のための特殊な結果
  4. エラー処理: エラー通信のための標準化されたアプローチ

このパターンにより、層間に明示的で追跡可能な通信が生まれます。

イベントベース通信

非同期プロセスのために、Prism Architectureはイベントベースのアプローチを使用します:

  1. ドメインイベント: 重要な出来事を示すためにドメイン層によって生成される
  2. イベントハンドラー: イベントに応答するためのオーケストレーション層内
  3. ワークフロートリガー: ワークフローを開始または進行させるイベント
  4. プレゼンテーション通知: プレゼンテーション層に送信されるイベント

このアプローチにより、層の分離を維持しながらリアクティブな振る舞いが可能になります。

ビジネスロジックのテスト

ドメインロジックテスト

ドメイン層コンポーネントのテストはビジネスルールに焦点を当てます:

  1. ドメインサービステスト: ビジネスルール実装の検証
  2. エンティティテスト: エンティティの制約と振る舞いの確認
  3. バリデーションロジックテスト: バリデーションルールの正確さの確認
  4. ドメインイベントテスト: 適切な条件下でのイベント生成の検証

これらのテストは技術的な統合ではなく、ビジネスの正確さに焦点を当てています。

オーケストレーションコンポーネントテスト

オーケストレーション層コンポーネントのテストは調整に焦点を当てます:

  1. ユースケーステスト: 依存関係の正しい調整の検証
  2. オーケストレーションサービステスト: ユースケースの適切な構成の確認
  3. ワークフローテスト: 正しいプロセスフローと状態管理の確保
  4. イベントハンドラーテスト: イベントへの適切な反応の検証

これらのテストでは、調整ロジックを分離するために依存関係のモックを使用します。

実装の実践的ガイダンス

ビジネスロジック配置のバランス

ビジネスロジックをどこに配置するかを決める際には、次のガイドラインに従ってください:

  1. ドメイン層の用途:

    • コアビジネスルールと不変条件
    • エンティティバリデーションと制約
    • ビジネス計算とアルゴリズム
    • ドメイン固有の操作
  2. オーケストレーション層の用途:

    • 操作のシーケンスと調整
    • トランザクション管理
    • エンティティ間の調整
    • 外部システムとの統合

階層の維持

クリーンな階層構造を維持するには:

  1. シンプルに始める: 個々の操作のためのユースケースから始める
  2. 機能でグループ化する: 関連機能のためのオーケストレーションサービスを作成する
  3. ワークフローを特定する: ドメイン横断プロセスをワークフローに抽出する
  4. 継続的にリファクタリングする: アプリケーションの進化に合わせて階層を調整する

コンポーネント編成

オーケストレーション層は通常、次のフォルダ構造に従います:

この構造はコンポーネントの階層的編成を反映しています。

避けるべき一般的なアンチパターン

ユースケースアンチパターン

  1. 肥大化したユースケース: 単一のユースケースに多すぎる機能を含める
  2. ユースケース内のドメインロジック: ドメイン層に属すべきビジネスルールを配置する
  3. 直接インフラストラクチャアクセス: インフラストラクチャにアクセスするために抽象化をバイパスする
  4. ユースケースチェーン: ユースケースが他のユースケースを呼び出す

オーケストレーションサービスアンチパターン

  1. 集約ベースのサービス: 機能ではなく、単に集約に基づいてサービスを作成する(例:UserOrcService
  2. 操作分割サービス: 同じエンティティのCRUD操作に対して別々のサービスを作成する
  3. ドメイン横断サービス: 複数の無関係なドメインにまたがるサービス
  4. ステートレスのみの考え方: 操作間で必要なコンテキストを維持できない

ワークフローアンチパターン

  1. モノリシックなワークフロー: 1つのワークフローで多すぎるプロセスを処理しようとする
  2. 状態管理の欠如: プロセス状態を適切に追跡しない
  3. ハードコードされたフロー: 変化に適応できないワークフローを構築する
  4. 技術プロセス重視: ビジネスプロセスではなく技術的プロセスを中心にワークフローを作成する

実世界の例

Eコマース注文処理

Eコマースアプリケーションでは、注文処理は次のように構成されるかもしれません:

ユースケース:

  • ValidateOrderUseCase: 注文詳細を検証する
  • CalculateOrderTotalsUseCase: 注文合計を計算する
  • ReserveInventoryUseCase: アイテムの在庫を確保する

オーケストレーションサービス:

  • OrderManagementOrcService: 注文関連の操作を調整する

ワークフロー:

  • CheckoutWorkflow: 支払い、在庫、注文ドメインにまたがるエンドツーエンドの決済プロセスを管理する

ユーザー管理

SaaSアプリケーションでは、ユーザー管理は次のように構成されるかもしれません:

ユースケース:

  • RegisterUserUseCase: ユーザー登録を処理する
  • UpdateUserProfileUseCase: ユーザープロフィール詳細を更新する
  • ChangeUserPasswordUseCase: ユーザーパスワードを変更する

オーケストレーションサービス:

  • UserManagementOrcService: ユーザー関連の操作を調整する

ワークフロー:

  • OnboardingWorkflow: 認証、プロフィール設定、権限ドメインにまたがる完全なユーザーオンボーディングプロセスを管理する

結論

Prism Architectureにおけるユースケースとビジネスロジックへの階層的アプローチは、アプリケーション機能を編成するための構造化された保守可能な方法を作成します。ドメインロジックをオーケストレーションロジックから明確に分離し、オーケストレーションコンポーネントの階層構造を使用することで、Prism Architectureは明確さと柔軟性の両方を提供します。

ユースケース、オーケストレーションサービス、ワークフローの3レベル階層は、操作の複雑さに合わせた自然な境界を作成します。シンプルなエンティティ重視の操作はユースケースによって処理され、機能領域の調整はオーケストレーションサービスによって、複雑なドメイン横断プロセスはワークフローによって処理されます。

これらのパターンに従い、アンチパターンを避けることで、開発者は構造が整っていて変化する要件に適応できるアプリケーションを作成できます。

次のステップ

  • ドメインサービス: ドメインサービスがどのように中核的なビジネスロジックを実装するかを探る
  • インフラストラクチャ統合: オーケストレーション層がインフラストラクチャ層とどのようにインターフェースするかを理解する
  • プレゼンテーション層統合: オーケストレーション層がプレゼンテーション層とどのように通信するかを学ぶ
  • イベント駆動アーキテクチャ: イベントがPrism Architectureでどのようにリアクティブな振る舞いを可能にするかを発見する