ルール駆動開発におけるビジネスルールの抽出方法

ビジネス変化に迅速に対応可能なアプリケーションの開発手法として、「ルール駆動開発」という手法があります。

業務アプリにおいて、業務ルール（業務ロジック）が正しく実装されていることは、何よりも大切なポイントですよね。
いくら見栄えや使い勝手がよくても、業務を正しく遂行できないアプリでは、意味がありません。

ルール駆動開発は、その業務ルールの実装に主眼を置いた開発手法です。
業務ルールを、高速にかつ品質良く実装し、運用時には業務ルールの変更が迅速に行えるアプリにするためのノウハウを詰め込んだ手法です。

ルール駆動開発について詳しく知りたい方は、こちらの過去記事をどうぞ。

[・ルール駆動開発をやってきてつくづく思うこと](https://qiita.com/Erina/items/9ab327339d9d4afc0256)

マンガで読みたい方は[こちら https://redhat.lookbookhq.com/rhdm_manga](https://redhat.lookbookhq.com/rhdm_manga) からダウンロード出来ます（お名前登録が必要になりますが無料です）。
![2021-08-18 17.13.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276989/446c3662-b8f0-e4b2-3cf2-8c121a258be7.png)

##"ビジネスルール"の切り出し方

さて、ルール駆動開発について説明をしていて、よく聞かれる質問の一つに「膨大な既存システムの要件から、業務ルールの切り出しをどうやって行うのか、イメージがつかない」というのがあります。

業務ルール部分を外に切り出して、「（業務ルールに基づいた判断を行う）デシジョンサービス」として独立したサービス化すべき、ということまでは理解されるのですが、業務ルールもUI関連ロジックもデータアクセスもごちゃまぜになっている、既存システムから、業務ルール部分を抜き出す、というのが難しいと感じられるようです。

![2021-08-18 17.54.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276989/5142d4a2-d56b-42df-b80c-2e10452a39a7.png)

そこで、今日は、どのように業務ルールを「デシジョンサービス」として切り出していくのかについて、解説したいと思います。

###まず最初にやること

「〇〇ならば■■する」というのがルール、と聞くと、現行プログラムでIF文で実装されているようなところをルール対象として抜き出していくのだろう、と思う人が多いですが、そういうアプローチはとりません。

IF文で実装されているような、細かなルール１つ１つに注目するのではなく、
ユースケースやイベント単位に、「何らかのインプットを元に、いくつかのパターンに応じた判断が行われ、アウトプットを出す」というような処理が中に含まれているかどうか、を見ていきます。

たとえば、以下のようなリストを作成します。
![16.28.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276989/19433be9-0b86-e554-10e3-73b4000d441f.png)
「アイテムを検索する」というユースケースは、入力条件に一致するデータを検索するだけで、業務ルールは特になさそうです。
一方、「オススメアイテムを表示する」というユースケースは、その顧客の購入履歴や閲覧履歴、また在庫状況や流行りのアイテムは何かといったデータを元に、何をオススメするかを決めるルールが必要になりそうです。デシジョンサービスの候補となりえます。
ルールエンジン適用可否、に○がつくところが、デシジョンサービスの候補になります。

###デシジョンサービスの形を決めていく

何らかのルールの塊がありそうな箇所（＝デシジョンサービスの候補）が、リストアップされたら、次はそれぞれについて、以下を定義していきます。

1. アウトプット
    - 最終的に何を求めるルールなのか？
    - ex)レコメンドする商品、入力値の妥当性チェック結果、来月の生産計画
1. インプット
    - アウトプットを求めるために必要になるデータは何か
1. 処理内容
    - どのような判断を経て、アウトプットにたどり着くのか


この作業を行う時に使うと便利なのが、**DMN**です。
DMNとは何か、については、[こちらの過去記事](https://qiita.com/Erina/items/8590727e782bea72c0ff)を参照ください。

DMNでモデリングすることで、デシジョンサービスの形が出来てきます。
ショッピングカートの情報から、請求金額とその内訳を算出する処理のモデリング過程の例を以下に示します。

![8.45.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276989/0c34f291-9acd-2eae-5538-2cf08a7e17f0.png)
![8.45.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276989/a23efbc0-144e-507b-138a-f2dc6ce1da7c.png)

この作業により、アウトプットとインプット、処理内容が見えてきました。
DMNでは、アウトプットの詳細項目は表現できませんが、ここでは、最終ゴールである請求金額と、途中のデシジョンでそれぞれ出されるアウトプット（手数料、送料、値引額等）も合わせて返却するサービスにします。
インプットは、DMNで角丸の四角で表されているため、明白です。
カートアイテム情報、キャンペーン情報などがインプットデータです。
そして、四角のデシジョンが、処理内容の概要になります。

インプットとアウトプットがある程度固まったら、これがこのデシジョンサービスのI/Fになります。
ルールの詳細を決めるより先に、インプットとアウトプットを決めて、I/Fを明らかにすることで、ルールの呼び出し元とルール側とで開発を並行して進めることが出来ます。

![19.20.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276989/4dbe5500-b88d-2f9b-d571-729285f30751.png)


デシジョンサービスの切り出し方については、以上です。
現行のプログラムコードからの抽出ではなく、実際の業務に即して、業務ルールによる一連の判断を、デシジョンサービスとして定義していく流れがイメージできたかと思います。


ついでに、切り出した後の詳細化についても、以下に簡単に解説します。

###ルール詳細をヒアリングしながら書き出していく

さて、デシジョンサービスの大枠が決まったら、次に、DMNで「デシジョン」としてモデリングした各判断ロジックについて、詳細をつめていきます。
たとえば、「値引額算出」では、どういう条件によって、どのように値引額を計算するのか、を業務担当者からヒアリング、または業務マニュアル等から見つけて整理していきます。

![19.28.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276989/1d601097-c3db-d527-7444-e0b9695bca46.png)

この時重要なことは、**明らかになったルールから実装し、すぐにテストをする**ということです。
ヒアリングやマニュアルの読解だけでは拾えない、例外的なルールというのが必ずあります。
それらをすべて抽出することを最初に目指すと、なかなか前に進みません。
そこで、とりあえず出来たところから、すぐにテストを実施できるようにし、**足りていないルールはテストがNGになることであぶり出していく**という方法をとります。

デシジョンサービスのテストは、インプットデータに対して、想定したアウトプットが出されているかどうか、という点をチェックします。
ルールが正しく実装されていくに連れて、データの一致率が上がっていきます。
そして、あらかじめ決めておいたゴール（過去X年分のデータが一致する等）まで到達したところで、ルールの開発は完成となります。

![19.42.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276989/d1ad89e2-2002-97ac-d507-7e475168017b.png)