クリーンアーキテクチャにおける Domain層と UseCase層の棲み分けを Bard と壁打ちをして自分なりに理解しました、の忘備録
この記事について
クリーンアーキテクチャを学んだことがなく 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