3層アーキテクチャ+MVCの通信の流れ

大嶋勇樹氏:こうやって話してくると、具体的に「じゃあコードをどういうふうに書くの?」「どういうクラスで書くの?」ということを疑問に思うかもしれません。派生形やちょっと違う例もいろいろありますが、典型的な例を1個書いています。

(スライドを示して)これが3層アーキテクチャとMVC(Model、View、Controller)ともいえる典型例です。クラス名のつけ方はいろいろあります。これはどういう構造になっているかというと、まずControllerが入力を受けつけます。入力というのは、通信みたいなものですね。Webアプリであればリクエストを受けつけます。

そしてControllerは、ビジネスロジック層にあるServiceを呼び出します。このServiceはデータベースにアクセスする用のクラス、ここではGatewayと書いています。Table Data Gatewayというパターンで実装した場合、“なんとかGateway”と名前をつけたり、Javaだと“なんとかDAO”みたいな名前をつけたりすることもよくあります。そういうデータベースにアクセスする用のクラスの中にSQLが書いてあるようなイメージを持ってもらえば大丈夫です。

そのサービスはデータベースにアクセスする用のクラスからデータベースと一致するような、例えば“なんとかRecord”やPlayer Recordなどのデータの入れ物を受け取って、ゴニュゴニョゴニョと処理をして、なにか戻り値の型、“なんとかOutput”や“なんとかDTO”と言ったりすることもありますが、それを返して、Viewはそれをそのまま使うか、変換してからかして使います。

こういうのが典型的な3層アーキテクチャです。単語としては“なんとかService”。Player Serviceの代わりにPlayer Logicという名前をつけたり、データベースのレコード、テーブルのレコードと一致するようなクラスを“なんとかEntity”みたいな名前をつけたりすることもあります。

また、データを入れる入れ物クラス。ただデータを入れて返すだけのためのクラスのことを“なんとかDTO”と呼ぶこともあります。ちなみにここで、Entityと出てきていますが、このEntityというのは、データベースのRecordと対応するクラスにそういう名前をつけることもあるし、ぜんぜん違う意味でアプリケーション設計の中でEntityという言葉を使うこともあって、すごくややこしいです。

(本セッションの)この後、こういう箇所ではRecordみたいな言葉を使っていければと思っています。

質疑応答 「HTMLを返す」はなぜフロントエンドに該当するのか?

ここで1つ、質問をもらったので回答しようと思います。質問はZoomのQ&Aの欄をクリックしてもらえれば、ほかの方の質問も見られるようになっています。バージョンによって見えない方もいるようなので読みます。

「HTMLを返す場合、プレゼンテーション層がフロントエンドに該当するのかよくわかりません。HTMLをサーバー側で生成して返すのであれば、それはサーバーサイドの動きではないのですか?」ということです。

それはそうですね。(スライドを示して)ただ、HTMLはブラウザ上でも処理されるものなので、フロントエンドといってもおかしくないぐらいのニュアンスです。

サーバーサイドでHTMLを生成して、ブラウザ上ではそのHTMLを解析していろいろ処理しているわけなので、フロントエンドをサーバーサイドで生成しているみたいな言い方はできなくもないかなと思っているぐらいですね。

ここの用語の使い方に、私はすごくこだわっているかと言うと……。ういう言い方をする人もいるとは思います。質問いただいた方の理解自体はけっこう合っている気はしています。私ともズレていないと思います。

大丈夫そうですね。(質問者の方から)「ありがとうございます」と(コメントを)いただきました。質問は気軽にしてもらえれば。どんどん回答します。ありがとうございます。

ビジネスロジック層は「プレゼンテーション層でもデータアクセス層でもないところ」

ということで、3層アーキテクチャの典型例みたいなものを見てきました。(スライドを示して)これがよくある例ですが、この中でなにが一番謎かというと、たぶんビジネスロジック(層)というものだと思います。

ControllerやServiceなど、データアクセス用のクラスにSQLなりO/Rマッパーを使った処理なりを書くのはなんとなくイメージがつきやすいし、Controllerがいったん受けつけている(という)ところはわかる気がします。

「じゃあ、このServiceはなにを書くところなんですか?」ということは私も最初はよくわからなかったし、「ビジネスロジックを書くところです」と言われても「なにを言っているんですか」という感じだったので、そこを深掘りしていければと思います。

ということで、ここから「ビジネスロジックとは」という話に入っていきます。

(スライドを示して)ビジネスロジックとはというところですが、(その前に)もう1回、プレゼンテーション層、ビジネスロジック層、データアクセス層の絵を描いています。

プレゼンテーション層は、アプリケーションの利用者とやりとりするところ。データアクセス層は、データベースやファイルといったデータの保存先とやりとりするところ。それに対してビジネスロジック層は、「システムのコアやシステムの目的の処理をするところ」とよく説明されます。「ビジネスロジック層は、システムのコアを書くところだよ」「システムの目的の処理を書くところだよ」と言われることがあります。

ただ個人的に、(ビジネスロジック層について)わかってくると確かにそう言いたくなる気持ちもわかるのですが、最初にこれを言われて理解するのは、けっこう難しいんじゃないかなと感じています。

“システムのコア”と言われても、 「それはビジネスロジックの言い換えにはあまりなっていないんじゃないか」みたいなことを感じたり、“システムの目的を処理するところ”と言われても、「例えばどういうことなんだ」という疑問がどうしても浮かぶと思います。

まずは「プレゼンテーションでもデータアクセスでもないところがビジネスロジック」と考えると、とっかかりとしてはすごくいいと私は思っています。

けっこう慣れてくると「まずビジネスロジックから考えるべき」みたいなところ(わかるようになります)。(ビジネスロジックは)コアと書かれるように、すごく重要なところなので、プレゼンテーションやデータアクセスではなく、ビジネスロジック中心に考えるべきだよねという話もあるし、私もそう思います。

ただ最初は、そうは言われてもなにがビジネスロジックなのかわからないと思うので、「プレゼンテーションでもデータアクセスでもないのがビジネスロジック」と考えると、第一歩としてはいいんじゃないかなと思っています。

ゲーム「リバーシ」からビジネスロジック層の役割を考える

(スライドを示して)具体例の話になりますが、「リバーシ」(というゲーム)を考えてみましょう。Webアプリでもモバイルアプリでもいいのですが、「リバーシ」を作ってみようという時に、盤面に石を打つようなことをすると思うんですね。

盤面に石を打つ時の処理の流れは、プレーヤーが石をどこに打つかをまず受けつけて、そしてデータアクセス層から盤面の状態を取ってきて、盤面に置けるかをチェックして、石をそこに置いて、挟まったやつをひっくり返して、盤面の状態をデータアクセス層を使って保存して、画面に新しい状態の盤面を表示するというのが一例です。こうじゃない可能性もありますが、例えばこういう流れになると思います。

このうち最初と最後については、ユーザーとやりとりしていますね。アプリケーションの利用者とやりとりするところ、つまりプレゼンテーション層ですね。入力を受けつけたり、画面を表示するのはプレゼンテーション層の役割です。

そして、データアクセス層のメソッドを呼び出すイメージですね。データベースにアクセスするメソッドを呼び出して、盤面の状態を取ってきて、置けるかチェックして、石を置いてひっくり返して、さらにまたデータアクセス層を使って保存します。このあたりがビジネスロジックです。「リバーシ」で石を打つ時の処理の例でいえばこんな流れになります。

こんなふうに、ビジネスロジックには利用者とやりとりする方法、例えば入力をどうやっているのか、それがAPIみたいな方式なのか、Webアプリで画面クリックしたのかみたいなところは関係ありません。画面の表示の仕方もこの間には関係ないですね。

保存先のデータベースの種類も、データアクセス層の先に隠蔽されていれば、メソッドとして呼び出すだけであれば、ビジネスロジックの中には関係ないわけです。このあたりがまさにビジネスロジックの例であって、ビジネスロジック層に書くべきコードの例です。

同じ処理でもアプリケーションの性質でビジネスロジック層の役割かどうかは変化する

これだけだと、例が少ないと思うので、もういくつか見ていこうと思います。

(スライドを示して)これは「ビジネスロジックかどうか」みたいなやつです。これはすごくよくある例だと思いますが、見た目を整えるために、日付時刻の形式を「何年何月何日」みたいな形式に変換することはよくあると思います。

これがビジネスロジックかというと、見た目を整えるための日付時刻の形式変換はUIを整えるための処理、(つまり)プレゼンテーション層の役割であって、ビジネスロジックではないと言われる、判断されることが多いです。

ここが難しいところでもあるのですが、もしも日付時刻形式変換アプリケーションみたいなものを作ったとすると、その場合、日付時刻形式変換はアプリケーションの中のコアみたいなものですね。

“コア”という結局わかりにくい言葉を使っていますが、そのアプリケーションが本当にやりたい処理は日付時刻の形式変換であって、そういう時は、この処理はビジネスロジックであると言えると思います。

こんなふうに、同じ処理でもアプリケーションの性質次第で、ビジネスロジックかどうかが変わることがあります。

特に日付時刻の形式変換は、だいたいの場合、プレゼンテーション層の役割と言われることが多いと思います。しかし、もし日付時刻形式変換がメインのアプリケーションだったらそれはビジネスロジックというか、「そのアプリケーションの一番重要なロジックだよね」となるということですね。

質疑応答 「リバーシ」の石を置いたりひっくり返すステップもビジネスロジックに該当するか?

1個質問をもらったので回答しようと思います。「石を置いたりひっくり返すステップもビジネスロジックと呼ばれるのでしょうか?」ということです。

そうですね。石を置いたりひっくり返す処理も、私はビジネスロジックだと思います。この「石をひっくり返す」が何を指しているかですが、画面上でひっくり返すアニメーションを指しているのであれば、それはビジネスロジックではないですね。

アニメーションみたいなものは表示上の話で。(ただ)それもアプリケーションの種類次第なところはあります。例えば毎ターン、盤面の状態をデータベースに保存するようなことを想像してもらいたいのですが、Webアプリで石を置いたりひっくり返す時は、たぶん内部に2次元配列みたいなものを持っていて、その配列の値を変えたりすると思うんですね。

「ここからここはひっくり返りそうだ」みたいなチェックをしてひっくり返すと思うのですが、そういうチェックしている処理はビジネスロジックですね。

一方、ここでは新しい盤面を表示するという中で表示上のひっくり返りが動くイメージでしたが、それがビジネスロジックかというとそうではないですね。質問ありがとうございます。確かにこの例だとわかりにくかったかもしれないですね。ありがとうございます。

(次回に続く)