little hands' lab

ドメイン駆動設計、アジャイルプラクティスを実践し、解説しています。

ドメイン知識とユースケースの違いは何か?[ドメイン駆動設計][DDD]

DDDの文脈の中で、
「ドメイン知識とユースケース(≒アプリケーションの知識)は何が違うのか?」
という疑問がよく持たれます。
この記事ではその違いを説明し、DDDのコードにどう反映するかを書きます。

あるToDoアプリの仕様

事例として、ToDoアプリの話をします。
「仕様を決める」と言ったとき、以下のように箇条書きで決めることがあると思います。(Jiraのようなチケット管理システムのチケット詳細として書いたりしますよね)

  • ユーザー登録、非活性化ができる
  • メールアドレスは重複登録できない
  • タスク登録、更新、完了、未完了に戻す、延期、ユーザーへのアサインができる
  • タスクは3回までしか延期ができない
  • 非活性化されていないユーザーにアサインができる
  • タスクを完了、アサインするとタスクレポートが作成される

これはいわゆる「ビジネスロジック」と呼ばれて、3層レイヤーのアーキテクチャではBusinessLogic層と呼ばれる層に書くように決めたりします。

さて、ここまでに何か問題はあるでしょうか?

身に覚えのある方はいらっしゃると思いますが、そう、 BusinessLogic層がどんどん肥大化していきます。

XxxService, XxxLogicと言ったメソッドが超大量にあるクラスを見たことがある方も多いのではないでしょうか。

これを避けるにはどうしたら良いでしょうか。

ユースケース図

ここで、先ほどの「仕様」と書いたものを、ユースケース図とルール/制約という観点で整理してみます。

ます、ユースケース図を書いて見ます。

ルール/制約

次に、このアプリケーションのルール/制約を整理してみます。

  • ユーザー
    • メールアドレスは重複登録できない
    • 最初は活性状態で作成され、非活性化できる
    • ユーザーは姓名、メールアドレスを持つ
  • タスク
    • タスクは期日を持ち、3回まで延期ができる
    • 非活性化されていないユーザーにアサインができる
    • 最初は未完了状態で作成される

元の仕様を二つに分けることができました。

ここで改めて見てみると、元の「仕様」には
性質が大きく異なるものが一緒に並べられていた
ということに気づくことができるのではないでしょうか。

後者に分類されるルール/制約のことを、「ドメイン知識」と呼びます。

この2つについて定義を書きます。

  • ユースケース
    • ユーザーとソフトウェアの間の相互関係を起こすアクション
    • "このソフトウェアの"ユースケースであり、アプリケーションがなければ存在しない
  • ドメイン知識
    • ソフトウェア化する対象領域に存在するルール
    • ソフトウェアがなくても、現実世界に存在する

ドメイン知識についての補足

「ドメイン」というのは、現実世界のソフトウェア化する対象のことを指します。ドメイン知識は、現実世界における知識、という意味合いが含まれます。

例えば、ソフトウェアを作る前に、ToDoを付箋で管理していたとします。
その際にも「付箋に期日を書くようにする」「日付は3日までしか伸ばしてはいけない」というルールで運用することは可能です。今回の開発において、実際に現実にあったルールを、ソフトウェアに落とし込むという捉え方ができるのです。

一方、例えば入力値のバリデーションとかユーザー認証という概念は、ソフトウェアがなければ存在しません。

このように、現実世界にあるルール/制約か、そうでないかという観点で、ドメイン知識とそうでないかを切り分けることができます。

アーキテクチャとの関係

新卒にも伝わるドメイン駆動設計のアーキテクチャ説明で紹介した以下のアーキテクチャを見て見ましょう。

もとはBusinessLogic層に詰め込まれていたものが、切り分けたユースケース/ドメイン知識に基づいてそれぞれApplication層(UseCase層)、Domain層にマッピングされます。
これにより、冒頭で懸念してしていた、BusinessLogic層の大幅な肥大を防ぐことができます。レイヤの責務がより明確になり、凝集度が上がり、コードのメンテナンス性を大幅に向上することにつながります。

ドメインモデリング

DDDで実装前に行うドメインモデリングでは、ユースケースとドメイン知識を順番に整理するところから始めます。
現場でDDD!のハンズオン、持ち帰ってやってみたではその具体例を紹介しました。

まとめ

このように、ユースケースとドメイン知識を切り分け、実装にも反映することで、コードの凝集度を大きく上げてメンテナンス性が高いコードを書けるようになります。
この際に、必ずしもDDDのEntityなどの実装パターンを使用する必要はありません。まずはレイヤーで分けるだけでも大きな違いが出ます。
今までは区別していなかったものについて、ぜひ意識を向けて試して見てください。

もっと詳しく知りたい方は

little-hands.booth.pm

初めてDDDを学ぶ方、もしくは実際に着手して難しさにぶつかっている方向けの書籍を出しました。
迷子になりがちな「DDDの目的」や「モデル」の解説からはじめ、 具体的なモデリングを行い実装まで落とす事例を元に、DDDの魅力や効果を体感することを目指します。

この本の「第5章 アーキテクチャ」では、本ブログ記事の内容をさらに詳細に解説しています。よろしければお求めください。


また、実践にあたって頻出の疑問に対してトピックごとに詳しく解説した書籍もあります。

重要トピック「モデリング」「集約」「テスト」について詳細に解説し、その他のトピックでは頻出の質問への回答と具体的なサンプルコードをふんだんに盛り込みました。現場で実践して、困っていることがある方はぜひこちらもご覧ください。

little-hands.booth.pm

現場での導入で困ったら

DDDを導入しようとすると結構試行錯誤に時間がかかります。
現場で導入してすぐに効果を発揮したい!!という方向けに、基礎解説とライブモデリング/コーディングを行う勉強会の開催や、設計相談を受付ております。
事例紹介もあるのでご関心あれば覗いてみてください。開催形式は柔軟に対応できるのでお気軽にご相談ください。

little-hand-s.notion.site

Twitterでも、DDDに関して発信したり、「質問箱」というサービスを通じて質問を受け付けています。こちらもよろしければフォローしてください。

https://twitter.com/little_hand_s

YouTubeで10分でわかるDDD動画シリーズをアップしています。概要を動画で理解したい方はこちらもどうぞ。チャンネル登録すると新しい動画の通知を受け取ることができます。