ユースケースの洗い出し | ドメイン駆動設計ハンズオン

Prev: フィーチャーツリーを作る

誰がユースケースを考えるか

ユースケースを考えるのはプロダクトオーナーの仕事になるでしょう。スクラムを行っているなら、ユーザーストーリーという形でPBIが積まれると思います。そのユーザーストーリーを洗い出すというのがこの章の目的です。当然、PBIを積むときと同じように必要以上の詳細化は不要で、実装するときまでに十分に詳細化できていればよいです。

ユースケースを作る

フィーチャーツリーは以下の通りでした。

  • 決済機能
  • ユーザー情報変更
  • 商品カタログ
    • 商品の検索
    • 商品管理
  • 注文
    • ショッピングカート
    • 注文受付機能
    • 配送状態確認

これを元にユースケースを考えていきます。

管理者が商品を登録する。
ユーザーが商品を検索する。
ユーザーがショッピングカートに商品を追加する。
ユーザーがショッピングカートの中身を確認する。

いくつかフィーチャーツリーの機能を省略していますが、本ハンズオンでは上記のユースケースの実装を考えていきます。また、上記の1行1行に対応するようにApplicationServiceを作成していきます。

Next: 管理者が商品を登録する

フィーチャーツリーの分類とユースケースの分類

フィーチャーツリーで分類したのだから、ユースケース、つまりApplicationServiceもフィーチャーツリーの通りに分類すれば良いと考えるかもしれません。しかし、実際にはそううまくいきません。

例えば、「ユーザーが注文を確定する」ユースケースで必要になる機能は何でしょうか。注文グループの注文受付機能は当然必要になります。しかし、決済機能も必要になるはずですし、在庫の確保などの機能があるなら、それらの機能も利用することになります。

# ユーザーが注文を確定するユースケース
class UserConfirmOrder
  def perform(params)
    ActiveRecord::Base.transaction do
      # 決済を実行する処理
      # 注文を確定する処理
      # 在庫を確保する処理
    end
  end
end

このように1つのApplicationServiceが複数の機能グループにまたがって実装されることはありえます。教科書的にはこういった状況はイベントソーシングを用いて結果整合性で解決すべきなのかもしれませんが、いずれにせよ1つのユースケースが複数の機能をトリガーしているのだから意味的には同じになります。つまり、フィーチャーツリーによる機能分類をそのままユースケースの分類として使うことは難しいということです。

そのため、私はdomainsディレクトリとusecasesディレクトリを作成し、domainsディレクトリはフィーチャーツリーに基づいたModule(Package)を作成し、usecasesディレクトリにはフィーチャーツリーとは別体系のモジュールで分類したApplicationServiceを格納するというふうにするのが良いと考えています。

Next: 管理者が商品を登録する