はじめに
今回はポイント管理システムをテーマに
DDD×クリーンアーキテクチャでサンプルコードを作ったので、
それを使いながら、
ユースケース(アプリケーション)とは何??どう使う??
についてまとめました。
動画にもまとめたのでこちらもご覧ください。
ユースケース(アプリケーションサービス)のサンプルコード
今回テーマにしているポイントシステムでは、
店舗からレシート情報とカード、ポイント利用などを連携され、
付与ポイントの加算、ポイント利用の減算などの
ポイント管理ができるシステムを想定しています。
まずは支払登録ユースケースを実現する
サンプルコードを見てみましょう。
fun execute(param: Param) {
receiptNumberDuplicationCheckService.execute(param.receiptNumber)
val paymentPurchases = param.paymentPurchases.map { PaymentPurchase.create(it.memberCompanyGoodsCode, it.purchaseQuantity, it.goodsPrice) }
val paymentMethods = param.paymentMethods.map { PaymentMethod.create(it.paymentMethodCode, it.paymentMethodAmount) }
val payment = paymentFactory.create(
param.receiptNumber,
param.paymentDate,
param.paymentAmount,
param.memberCode,
param.usePoints,
param.shopCode,
param.couponCode,
paymentPurchases,
paymentMethods
)
paymentRepository.save(payment)
val distributionCoupon = distributeCouponRepository.findBy(param.memberCode)
distributionCoupon?.let { distributeCouponRepository.update(it) }
}
ドメインサービスを利用してレシート重複チェックをしたり、
ファクトリーを利用してユースケース実現に必要な
支払エンティティを生成したり、
(エンティティ生成時に付与ポイントは算出される)
リポジトリを利用して支払エンティティを永続化したりしています。
ユースケース(アプリケーションサービス)の役割
エンティティや値オブジェクトなどの
ドメインオブジェクトを組み合わせたり、
リポジトリを使ってDBから値を取り出してエンティティを再構築、
リポジトリを使ってエンティティをDBへ永続化、
外部サービス連携などを行いながら
1つのユースケースを実現するのがユースケースの役割です。
また、
ユースケースにはコントローラー的な役割に専念させるべきなので、
ドメインオブジェクトが持つような業務ロジックを置いてはいけません。
ユースケースに業務ロジックを書きたくなったら、
ドメインオブジェクトがを見直すサインです。
この辺りについては、
テストコードの視点から解説した記事があるのでそちらをご覧ください。
(ユースケースのテストコードの書き方もこちらの記事に書いています)
テスト対象を分析して4つに分ける〜テストコードのきほん〜今回のテーマについては以上です。
DDD実践のためのきほんシリーズのまとめ記事を作りました。
是非こちらもご覧ください。
初めてドメイン駆動設計を実践する方に向けて〜DDD実践のためのきほん〜参考文献
第7章 ユースケース(アプリケーション)層の実装
ドメイン駆動設計 モデリング/実装ガイド
Chapter6 ユースケースを実現する「アプリケーションサービス」
ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本