📌

クリーンアーキテクチャにおける Domain層と UseCase層の棲み分けを Bard と壁打ちをして自分なりに理解しました、の忘備録

2023/10/15に公開

この記事について

クリーンアーキテクチャを学んだことがなく Domain層と UseCase層の違いがいまいち理解できていない人間が Bard と壁打ちをして自分なりに納得した答えに辿り着いたので、その忘備録です。
Bard との壁打ちではなく、クリーンアーキテクチャについての自分なりの整理についての忘備録です。
きっかけはこの記事を読んで前提知識が足りていないと感じたためです。

クリーンアーキテクチャとは

クリーンアーキテクチャとは、ソフトウェアの設計とアーキテクチャに関する考え方です。
クリーンアーキテクチャでは、アプリケーションを以下の 5 つの層に分割します。

  • Domain層
    • ビジネスルールやドメインモデルを定義する
  • UseCase層
    • アプリケーションのビジネスロジックを定義する
  • Controller層
    • ユーザーからの要求を受け取り、UseCase層のビジネスロジックを実行する
  • View層
    • ユーザーに情報を表示したり、ユーザーからの入力を受け付けたりする
  • Infrastructure層
    • データベースやファイルシステムなどの外部リソースを操作する

このうち Domain層と UseCase層が、言いたいことはわかるものの実際どこまでがドメインモデルでどこからがビジネスロジックなのか曖昧だったため Bard に色々と質問した結果、自分なりに納得できる答えに辿り着けました。

DDD における UseCase と Domain の定義

DDD における UseCase と Domain は、以下のように定義されます。

  • UseCase
    • ユーザーがアプリケーションに要求する機能
    • ユーザーの行動を表現する
  • Domain
    • アプリケーションのビジネスドメインを表現する
    • ビジネスルールやドメインモデルで構成される

UseCase の例

  • 商品を検索する
  • 商品をカートに追加する
  • 商品を購入する

Domain の例

  • 商品
  • カート
  • 注文

UseCase は、ユーザーの行動を表現するものであり、Domain は、アプリケーションのビジネスドメインを表現するものであるという点がポイントです。

サンプルコード

商品の購入処理を例に実際のコードベースでの UseCase と Domain の棲み分けを見ていきます。
ドメインモデル、ドメインルールをモデルのフィールドやバリデーションロジック、ビジネスロジックをユーザーの具体的なアクションにおけるドメインの操作、と理解し、以下のようなコードにまとめました。

# Domain層

class Product < ApplicationRecord
  validates :name, presence: true
  validates :price, presence: true
  validates :stock, presence: true
end

class Order < ApplicationRecord
  belongs_to :product
  belongs_to :user
  validates :quantity, presence: true
end

# UseCase層

class PurchaseProductUseCase
  def initialize(product_id:, quantity:)
    @product_id = product_id
    @quantity = quantity
  end

  def execute
    # 商品の取得
    product = Product.find(@product_id)

    # 購入者の取得
    user = current_user

    # 注文の作成
    order = Order.new(product: product, quantity: @quantity, user: user)
    order.save!

    # 商品の在庫数を減らす
    product.stock -= @quantity
    product.save!

    # 購入完了の通知を送信する
    UserMailer.product_purchased_email(order).deliver_now
  end
end

UseCase と Domain の棲み分けによるメリット

DDD における UseCase と Domain の棲み分けは、アプリケーションの設計と開発をより効率的かつ効果的に行うための重要な考え方です。この棲み分けを行うことで、以下のメリットが得られます。

  • テストや保守がしやすくなる
    • UseCase と Domain を疎結合にすることで、それぞれの層を個別にテストしやすくなります。
    • Domain の変更が UseCase に影響しにくくなるため、保守しやすくなります。
  • 変更がしやすくなる
    • Domain を疎結合にすることで、Domain の変更が UseCase やアプリケーションの他の部分に影響しにくくなります。
  • アプリケーションの可読性や理解しやすさが向上する
    • UseCase と Domain を明確に分離することで、アプリケーションの構造が明確になり、可読性や理解しやすさが向上します。

Discussion