
2025.02.12
職員一人あたり52時間の残業削減に成功 kintone導入がもたらした富士吉田市の自治体DX“変革”ハウツー
リンクをコピー
記事をブックマーク
大嶋勇樹氏:ここまでの流れは、「そもそも3層アーキテクチャって何だっけ?」というところから、特に「真ん中のビジネスロジックって何だっけ?」と(いう話)、「例えば、このあたりがビジネスロジックだよね」と(いう話)。(そして)「ビジネスロジックの中には、ドメインロジックとユースケースの2種類があると考えるとわかりやすいですよ」というところまで話してきました。
ドメインロジックは、システム都合ではないコアなルールみたいなもので、ユースケースは処理の流れを実現することです。これを踏まえて次は、ビジネスロジックの実装方式を見ていこうと思います。
と思ったんですが、ちょうど(発表を始めてから)50分(経った)ぐらいのタイミングなので、ここで5分休憩しようと思います。その間に質問があれば、Q&Aに書いてもらえれば回答します。
(5分経過)
5分経ったので、続きをやっていければと思います。
(スライドを示して)また「リバーシ」で石を打つ時の処理の例を見てみると、2つ目あたり(から)がビジネスロジックです。ここをすごく単純化して言うと、データの取得やデータの取得の呼び出し、データアクセス層のデータ取得のメソッドの呼び出しがあって、チェックやひっくり返す計算処理があって、最後にデータを保存する処理の呼び出しがあります。
これを踏まえて見ていこうと思いますが、実はビジネスロジックの実装方式は、トランザクションスクリプトパターンとドメインモデルパターンという、2種類の実装パターンがあります。
(スライドを示して)2種類を並べて見ています。トランザクションスクリプトパターンは、Serviceクラスみたいなところに、データの取得の呼び出しやチェック、計算処理、データの保存の呼び出しみたいなことを全部実装します。
つまり、ビジネスロジックと言われていたものが全部入るんですね。ユースケースで、処理の流れや「ここはひっくり返せるか」みたいな具体的なチェック、「この石をひっくり返す」みたいな具体的な処理、ドメインロジックも書いてあります。
プラス、このServiceクラスはDTOやModelと言われたりする、データを入れるだけのクラスを使っていることが多いです。Modelと呼ぶかどうか、Modelという単語はいろいろな意味がありすぎて状況によるので、「Modelという言葉が使われることもありますよ」ぐらいの意味でここでは言っています。
こういうDTOやModelというデータの入れ物を置いておいて、Serviceにメソッドというか、処理が全部書いてあるのがトランザクションスクリプトというやり方です。
(スライドを示して)一方、別のやり方としてドメインモデルパターンもあります。ドメインモデルパターンはなにが違うかというと、Serviceはユースケース、処理の流れを担うだけで、ドメインロジックをModelが持っています。ドメインロジックは、チェックや計算処理をデータの入れ物になるクラスに一緒に持たせるやり方ですね。
(スライドを示して)ちょっと特徴を並べてみますが、トランザクションスクリプトパターンはデータの入れ物と処理を分離するやり方で、手続き型プログラミング的とよく言われます。
Serviceなり、なんとかLogicというクラスが、ドメインロジックとユースケースを担当します。この実装方式は、メリットとして学習コストが低いというか、プログラミングを勉強し始めて、別のやり方を教わらずに「コードを書け」と言われたら、この方式を書く人がほとんどだと思います。そういう意味で学習コストが低いです。
一方で、この実装方式をすると、Serviceクラスにいろいろなロジック、いろいろな分岐や処理が書かれるので、肥大化しやすいです。同じLogicがServiceクラス間に分散しやすく、変更に弱いという特徴もあります。
一方で、ドメインモデルパターンは、データの入れ物に処理も持たせる方式です。言ってしまえばオブジェクト指向プログラミング的ですね。オブジェクト指向プログラミングといっても指す意味が人によってけっこう違いますが、ここでは「データの入れ物に処理、メソッドを持たせるようなもの」をオブジェクト指向プログラミングと言っています。
そういうやり方で、Modelはドメインロジックを担当して、Serviceはユースケースを担当します。
こういう構成にすると、メリットとしてはServiceクラスが肥大化しにくく、同じロジックが分散しにくくて変更に強くなりやすいです。そしてトランザクションスクリプトの裏返しですが、デメリットとしては学習コストが高いこと。オブジェクト指向的なコードの書き方みたいなものが、ある程度わかっていないと書けないところですね。
今1個質問をもらっていて、すぐ回答できそうなので回答しようと思います。「ドメインモデルパターンはドメインモデルにModelクラスを定義して、Serviceは、Modelクラスからメソッドを呼び出すみたいなイメージですか?」ということですが、そうですね。
ドメインモデルパターンはModelクラス。Modelクラスというものはけっこう曖昧ですが、とにかく何かデータを持っているようなクラス。何かフィールド、データを持っているクラスを用意して、そこにメソッドも持たせて、サービスからそのメソッドを呼び出すイメージです。質問ありがとうございます。そういう構成ですね。
そうすると、Serviceはユースケースを担当するだけで、Modelはドメインロジックを担当する。そういう分担ができます。これはいわゆるオブジェクト指向的な設計みたいな知識が必要で、ちょっと難易度が高いです。
(スライドを示して)具体的にどういう構成例になるかというと、ビジネスロジック層をアプリケーション層とドメイン層という2層に分割した例になります。こういう構成例が取れます。レイヤードアーキテクチャということもありますね。
これはプレゼンテーション層、アプリケーション層、ドメイン層、データアクセス層と、一方向に矢印があります。ここで矢印は呼び出しや依存の向きを表現していますが、一方向に流れているものをレイヤードアーキテクチャと呼んだりします。
どんな中身かというと、まずControllerは利用者から入力を受けつけたりして、Serviceを呼び出します。Serviceには、データを取り出してチェックしたり、計算して保存する処理の流れの呼び出しだけが書いてあります。
データを取り出すところは、データとデータベースでやりとりするようなクラスを使って、入れ物のクラスを受け取ったりするか何らか(の方法)で受け取って、ドメインモデルにロジックが書かれます。
この構成例だと、恐らくデータの入れ物を取り出したら、Serviceの中でドメインモデルの型に詰め替えることになります。ドメインモデルのクラスにデータを詰め替えて、そこでメソッドを呼び出してロジックを実行します。
最終的に計算結果をデータベースに保存するイメージです。プラス、戻り値を返してUIを表示します。ざっくりこんなイメージです。
もうちょっと凝るというか、もうちょっと工夫すると(したら)、よくあるのはRepositoryパターンを使うやり方です。
(スライドを示して)データベースのテーブル都合で読み書きするTable Data Gatewayのような設計パターンを使うのではなくて、ドメインモデルの形式で最初からデータを読み書きするデータアクセス用のクラス、Repositoryみたいなものを使って、Serviceはドメインモデルを簡単に取り出せるようにします。
その中ではTable Data Gatewayみたいなものを使うのか、O/Rマッパーを使うのかわかりませんが、とにかくなんとかデータベースからデータを取り出して、ドメインモデルのかたちに変換して返すようなことをするRepositoryを使います。
ServiceはRepositoryからドメインモデルを取り出して、ドメインモデルを操作して、Repositoryに保存するようなやり方は、わりとよくある例だと思います。このような構成はレイヤー化アーキテクチャと言ったりしますね。
今、1個質問をもらっていて。「ドメインモデルパターンはドメイン駆動設計と同義ですか」ということですが、私はノーだと思っています。ドメイン駆動設計との関係については、最後に補足しようかなと思います。ありがとうございます。
(スライドを示して)こんなものがドメインモデルパターンを使ううちの、けっこう典型的な構成の一種みたいな感じです。
(スライドを示して)ここまで「なんとかパターン」とか、「なんとかアーキテクチャ」とかいろいろ出てきましたが、今日出しているようなアプリケーションの設計の話の中には、いろいろな観点があります。
まず層分けをどうするかという話で、3層アーキテクチャ、レイヤードアーキテクチャ。ほかにもヘキサゴナルアーキテクチャ、オニオンアーキテクチャなどがあります。
層はだいたい3層なり、先ほど見せたようなビジネスロジックの部分をアプリケーション層、ドメイン層に分離するなりだったりします。そのうちプレゼンテーション層の実装方式もいろいろあって、MVC(Model、View、Controller)やMVVM(Mode、View、ViewModel)があります。
ビジネスロジック層の実装方式もいろいろあって、トランザクションスクリプトにするのか、ドメインモデルにするのか。データアクセス層はTable Data Gatewayにするのか、Repositoryにするのか。ほかにもいろいろあります。
こんなふうに、まず層分けがあって、そして各層のアーキテクチャ、設計パターンがあると考えるとちょっとわかりやすいかなと私は思っています。層分けと各層の実装方式という観点があって、組み合わせはいろいろあります。
その一例が、先ほどお見せしたレイヤードアーキテクチャ。プラス、プレゼンテーション層あたりはControllerとViewとMVCっぽくなっていますね。
(スライドを示して)Modelがどれかというと、アプリケーション層からデータアクセス層あたり全体がModelと言ってもいいのかもしれないし、Viewが直接見ているデータの入れ物をModelと言うのかもしれないし。そういう意味ではMVCのMはけっこう曖昧ですが、なんとなくMVCです。
プラス、ビジネスロジックの実装はドメインモデルパターンを使っていて、ドメインロジックはドメインモデルに持たせて、ユースケースはServiceクラスなりUseCaseなりの名前をつけることもありますが、そういうところに持たせます。
データアクセスする時はRepositoryを使っています。ただ、Repositoryの中ではTable Data Gatewayという別の設計パターンを使っています。こういうことがあったりするわけですね。
1個戻ると、例えばほかの組み合わせとしてよくあるのは、3層、MVC、トランザクションスクリプト、Table Data Gatewayとかです。前のほうで見た例ですね。
(スライドを示して)これは3層アーキテクチャに加えてMVC、さらにトランザクションスクリプト、さらにTable Data Gatewayみたいになっているわけです。
こんな感じで、層分けと各層に実装方式があると整理するとけっこうわかりやすいかなと私は思っています。
質問をもらっていますが、もう少し切りのいいところまで進めさせてもらいます。
アプリケーション設計にはいくつか異なる観点があります。1つは層をどうやって分けるかみたいな話です。3層、レイヤード、ヘキサゴナル、オニオン。そして各層をどうやって実装するか。MVC、MVVM、MVP、トランザクションスクリプト、ドメインモデル。Table Data Gateway、Repositoryなどいろいろありますが、各層をどう実装するか。そしてもう1つ。ドメインモデルをどうやって設計・実装するかという観点もあります。
この中でどれが重要かというと、全部重要だと思いますが、ドメインモデルをどう設計・実装するかがすごく大事ですね。最初はController、Serviceという役割分担に目が行きやすいのですが、それと同じかそれ以上に、ドメインモデルをどうやって設計するか、どうやって実装するかも大事です。
アプリケーション設計に関する書籍を読んだりする時は、この中のどの観点を今解説しているのか、また書籍全体でどこの観点を解説しているのかに注目すると、わりと理解しやすくなるかなと思っています。
ドメインモデルの設計・実装については、オブジェクト指向設計を解説した本の内容も役に立つので、そういうのも見てみるのもすごくいいかなと思います。
いろいろな言語であると思いますが、例えば『リファクタリング』もそうだし、Rubyの『オブジェクト指向設計実践ガイド』もそうだし、そういうのは「ドメインモデルをどう実装するか」にけっこう活かしやすい気はしています。
ほかのところにも活かせる点はありますが、特にドメインモデルの設計に活かしやすい気はしています。
1個質問をもらったので回答しようと思います。「Repositoryパターンを採用する基準などはありますか? ドメインモデルから直接呼び出したくない都合があるとかですか?」ということです。
Repositoryパターンはちょっと説明が難しいので、この場では曖昧にしか説明しなかったのですが、実はちょっと発展的な設計パターンです。
まず前提として、データベースと1対1対応するようなデータの読み書きクラスを作る時、それに(対して)Repositoryと名前をつけることがたまにあるのですが、それはRepositoryパターンではありません。
Repositoryパターンは、データベースのレコードと対応する読み書きクラスを作るわけではなくて。ドメインモデルはデータの入れ物兼ドメインロジックみたいな感じで、ドメインモデルに都合のいい単位で読み書きするクラスです。
もしRepositoryがないと、Serviceクラスがまずデータベースのレコードに対するクラスを取り出して、それをドメインモデルに詰め替えて、ドメインモデルの処理を呼び出して、データベースのレコードに対応するクラスに詰め替えて保存するみたいな流れになります。
その詰め替えの部分をRepositoryが担ってくれるイメージが、個人的には最初はけっこうしっくりきやすいかなと思っています。データベースのデータの入れ物なりなんなりから、ドメインモデルに詰め替えて扱います。保存する時もドメインモデルで渡せば、いい感じにデータベースに保存してくれるのがRepositoryです。
ここは実際のコードがあったほうがよりイメージはつきやすいと思います。Repositoryパターンは実は意外と難しいですね。質問ありがとうございます。
(次回に続く)
関連タグ:
“1つの独立して動く要素”の内部を整理し直す 「改めて整理するアプリケーション設計の基本」で伝えたいこと
アプリケーションアーキテクチャ理解に必要な“3層構造” プレゼンテーション層・ビジネスロジック層・データアクセス層それぞれの役割
3層アーキテクチャで最も謎な「ビジネスロジック層」 “システムのコア”をゲーム「リバーシ」で解説
「ビジネスロジックの処理は2つに分類すると整理しやすい」 4つの例から考える、プレゼンテーション層・データアクセス層の見分け方
ビジネスロジック層内部の2つの実装パターンを比較 選択時に考えたい、アプリケーション設計の観点
「クラスごとの役割を明確化すること」がポイント アプリケーション設計におけるドメインロジックの分離法
重要なのは「基本を押さえ、適したものを採用すること」 “本来の役割”を押さえたアプリケーション設計
2025.02.06
すかいらーく創業者が、社長を辞めて75歳で再起業したわけ “あえて長居させるコーヒー店”の経営に込めるこだわり
PR | 2025.02.07
プロジェクトマネージャーは「無理ゲーを攻略するプレイヤー」 仕事を任せられない管理職のためのマネジメントの秘訣
2025.02.06
落合陽一氏や松尾豊氏の研究は社会に届いているか? ひろゆき氏が語るアカデミアの課題と展望
2025.02.05
「納得しないと動けない部下」を変える3つのステップとは マネージャーの悩みを解消する会話のテクニック
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
2025.02.10
A4用紙を持ち歩いて殴り書きでアウトプット コクヨのワークスタイルコンサルタントが語る、2種類のメモ術
2025.02.05
エンジニアとして成功するための秘訣とは? ひろゆき氏が語る、自由な働き方を叶えるアプリ開発とキャリア戦略
2025.02.04
日本企業にありがちな「生産性の低さ」の原因 メーカーの「ちょっとした改善」で勝負が決まる仕組みの落とし穴
2025.02.03
「昔は富豪的プログラミングなんてできなかった」 21歳で「2ちゃんねる」を生んだひろゆき氏が語る開発の裏側
PR | 2025.02.04
能登半島地震で自宅は全壊、「これでどうやってDXするねん」 被災したサイボウズ社員と支援者らが語る災害支援のノウハウ
新人の報連相スキルはマネージメントで引きあげろ!~管理職の「他責思考」を排除~
2025.01.29 - 2025.01.29
【手放すTALK LIVE#45】人と組織のポテンシャルが継承されるソース原理 ~人と組織のポテンシャルが花開く「ソース原理」とは~
2024.12.09 - 2024.12.09
『これで採用はうまくいく』著者が語る、今こそ採用担当に届けたい「口説く」力のすべて
2024.11.29 - 2024.11.29
【著者来館】『成果を上げるプレイングマネジャーは「これ」をやらない』出版記念イベント!
2025.01.10 - 2025.01.10
片付けパパ対談【特別編】 整理術×行動術×メモ術で、仕事も人生も自在にデザイン!
2024.12.16 - 2024.12.16