リクエストの形式チェックはビジネスロジック層の役割か?

大嶋勇樹氏:(スライドを示して)続けて「これはビジネスロジック?」(というもの)をもう少し見ていこうと思います。2つ目として、リクエストの形式チェックがあります。

例えば、リクエストの必須パラメーターが足りているかとか、データサイズは決められた範囲内かとか、そういうチェックがあると思いますが、個人的にこれはプレゼンテーション層でチェックすべきものだと思っています。

なぜかというと、リクエストは利用者とのインターフェイス、利用者との境界での約束事に対するチェックなので、プレゼンテーション層が実施するべきかなと思っています。

また、不正なデータというものは、後に進んでしまい下手すると何か登録されてしまう可能性もあるので、プログラムがうまく動いていない(時)などは、セキュリティ的にもなるべく先に進めず、できるだけ早く(異常を)検知して以後のプログラムに進ませないようにしたいので、(リクエストの形式は)プレゼンテーション層でチェックしたいなと考えます。

もう1つは、データベースとやりとりする必要もないので、簡単に実装できるという理由もあります。なので、プレゼンテーション層ですべきチェックかなと思っています。

リクエストの形式より少しだけ複雑な条件チェックはビジネスロジック層の役割か?

(スライドを示して)またチェックのような話ですが、リクエストの形式より少しだけ複雑な条件チェックは、ビジネスロジック(で実施するもの)かと考えます。

例えば、SNSで自分には「いいね」できないようにするようなものや、TODO管理アプリみたいなもので、過去日のTODOは登録できないようにする(もの)とかですね。

これはロジック、分岐としてはすごく簡単で、実装としても数行ぐらいでできちゃうとか。数行かはちょっとわかりませんが、比較的簡単にできるかもしれないです。こういうもの(のチェック)は、私はビジネスロジックだと思っています。

なぜかというと、プレゼンテーション層は見た目などのUIに直接関わるようなことだけを知っているべきであって、こういう知識をプレゼンテーション層が持っているべきじゃないと思っているからというのが1つ(目の理由)です。

もう1つ、これは「GUIだからとかAPIだからとかコマンドだからこうしたいよね」みたいなルールではなくて、プレゼンテーション層の違いによらない、共通したチェックだと思うからです。

今回実装している、SNSで「自分には『いいね』できないというルールを作ろう」というのは、APIだからではなくて、そのSNSが本来持っているルールみたいなものです。なのでプレゼンテーション層の問題ではなく、ビジネスロジックじゃないかなと私は考えています。

ただこのぐらい簡易的なものになってくると、人によってけっこう意見が分かれることもあり得るかなとは思います。

データベースのデータとの整合性チェックはビジネスロジック層の役割か?

(スライドを示して)そして「これはビジネスロジック?」の最後。データベースのデータとの整合性チェックみたいなものはビジネスロジックかなと考えます。

例えば、「リバーシ」(の中)でデータベースに毎ターンの盤面の状態を保存しているとして、前のターンの盤面を取り出してきて、(次に)指定された場所に石を置けるか判定する。ほかにも、ECサイトで購入リクエストした商品が購入可能かチェックする。

このような、データベースのデータと整合性をチェックするようなことは、まさにビジネスロジック(がチェックするべきこと)だと私は思っています。ビジネスロジックという言葉もある程度曖昧で、人によって違う意見を持ったりするので「私は」とは言っていますが、「これはビジネスロジックである」と言う人がほとんどだと思います。

「リバーシ」の例でいえば「石をひっくり返す」「(ひっくり返すとしたら)どの点がひっくり返るか計算する」みたいな処理もまさにビジネスロジックですね。

このように、アプリケーションが従うべきルールのチェックやルールを適用する処理が、まさにビジネスロジックの中心です。

ビジネスロジック層の処理を「ドメインロジック」と「ユースケース」に分類する

(スライドを示して)ここで、ビジネスロジック層の処理をドメインロジックとユースケースの2つに分類して考えてみます。この2つに分類すると、実はちょっと整理しやすくなるんですね。

「リバーシ」で石を打つ時の処理の流れの例から「ビジネスロジックってここだよね」と言っていた部分をちょっと取り出してきました。ここには実は2種類の役割があります。

1個は、盤面に置けるかチェックしたり、石を置いたりひっくり返したりします。盤面に置けるかチェックするというのは、指定された点にもし置いた場合にひっくり返せる点があるか。もしなければ「そこには置けません」みたいなチェック(をすること)ですね。あるいは、石を置くとかひっくり返すとかの処理です。

これはシステムではなく、現実で「リバーシ」で遊ぶ時にも出てくるルールです。「こういうシステムだからどう」とかではなく、その物事に本質的に存在するルールをドメインロジックとかエンタープライズビジネスルールと言ったりします。今日はドメインロジックという呼び方をしようと思いますが、こういうルール、チェックみたいなものがまずあります。

そして、このビジネスロジック層で実装するものの中には、ほかにも処理の流れを実現するものもあります。どこかのサービスクラスかどこかに、データアクセス層を使って「盤面の状態を取得する」をして、盤面に置けるかチェックして、石を置いて、ひっくり返してデータアクセス層を使って、盤面の状態を保存する。

そんな感じの「なにかデータを取り出して、チェックして保存する処理の流れ」があると思います。そういうのは、ユースケースやアプリケーションビジネスルールと呼ばれたりします。今日はユースケースという言葉を使っていこうと思います。

こんなふうに2種類に整理すると、この後の「ビジネスロジックは実際どう実装するんだ」みたいな話が整理されやすくなってきます。

ホテルの予約からビジネスロジック層の役割を考える

「リバーシ」だけだと少ないかなと思ったので、ドメインロジックの例をもう1例ぐらい挙げています。

「リバーシ」であれば、盤面に置けるかチェックする処理や、挟まれた石をひっくり返す2次元配列のうち、「この点とこの点を0から1に置き換える、石をひっくり返す」ような処理がドメインロジックの例です。

ほかにも、例えばホテルの予約のアプリケーションを作ったとすると、指定された部屋に宿泊できる人数の予約かどうかをチェックする(機能)があると思います。

指定された部屋のマスターデータを見て、何人まで宿泊できるかを確認して、「今回泊まろうとしているのは何人で、人数をちゃんと満たしているな」とか。ほかにも「この人は予約できる条件を満たしているな」というチェックがあると思います。そういうものや「何日前のキャンセルだからキャンセル料はいくらです」という計算をするとか。こういうのがドメインロジックの例です。

ホテルの予約の例は、電話予約や対面の予約など、システムなしで人間が対応する時にもチェックするルールだと思います。

もしも電話予約で、人間がちょっと気を利かせてルールを破ってなにかをやってくれる可能性もあり得なくはないですが、人間が電話予約を受けつけて「何人ですか?」と聞いたり、「キャンセル料はいくらです」という話をしたりする時にも登場するルールだと思います。

こんなふうに、システムなしで現実で同じことをやろうとした時にも出てくるルールは、まさにドメインロジック。ビジネスロジックの中でも、コアなルールのわかりやすい例だと思います。

質疑応答 ビジネスロジック層のクラスを実装する時の命名方法は?

ということで、この後ビジネスロジックの実装方式の話をしていこうと思います。

ややこしい話をしてきたので、いったんここまでのQ&Aタイムにできればと思います。質問はQ&Aにもらえればと思います。1つ(質問)をもらっているものがあって、せっかくなのでこのタイミングで回答しようと思います。

「ビジネスロジック層のクラスを実装する時の命名は、およそどんなものがありますか? Handler、Manager、Controllerなど」ということです。

ここからビジネスロジックの実装方式について少し話すので、そこで出てくる言葉もあるし、この後にServiceにビジネスロジックを実装する以外の方式の話もしますが、例えばServiceにビジネスロジックを実装する時であれば、“なんとかService”とか“なんとかLogic”という名前がついていることが多い気はします。

あとControllerについては、ビジネスロジックはコントロールをしたいわけじゃないというか、Controllerにビジネスロジックが書いてあることはよくあるのですが、ビジネスロジックを実装するクラスにControllerとつけるのはあまり適していないかなとは思います。

Controllerはテレビゲームのコントローラーを想像してもらうとわかりやすいのですが、ただ入力を受けつけるだけで、ゲームの大事な処理はしないところです。ただ手で触るところがControllerです。ゲームのコントローラーを想像してもらうと役割が見えてくる気がしますね。ただビジネスロジック層に刺さっているだけの、入力を受けつけるだけの部品がControllerです。

Handlerみたいな図形は、どちらかというと個人的にControllerの代わりのHandlerという名前を見た気もします。

あとは、Managerみたいな名づけも(見たことがある気がします)。確かにServiceのところがManagerみたいになっている例は見なくはないですが、Managerという名前自体はあまりいい名づけではないと基本的には言われると思います。

Managerというと役割をすごく広く感じやすいので、あまりつけないほうがいいと言われることが多い気はしますね。真っすぐいくと、“Serviceか、なんとかLogic”が多いとは思います。質問ありがとうございます。

では、質問をいただいた範囲では回答できたので、続きにいこうと思います。

(次回に続く)