2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
リンクをコピー
記事をブックマーク
大嶋勇樹氏:ということで、ここまでビジネスロジックの実装について話してきました。ここからは最後のステップとして、「Controllerに全部書く」からどうやってステップアップするかを話していこうと思います。
ここまでで質問があれば、ぜひQ&Aにもらえれば回答します。せっかくなので、このタイミングで「ドメインモデルパターンはドメイン駆動設計と同義ですか?」(という質問)に回答しておこうと思います。
ドメイン駆動設計はドメインモデルパターンを使いますが、ドメインモデルパターンを使ったからといってドメイン駆動設計ではないという関係だと私は認識しています。こういう質問が来た時のために、私の横にホワイトボードを用意していたので、そちらを使って解説できればと思います。
せっかくなので、ドメイン駆動設計と今日話しているドメインモデルパターンの関係を話そうと思います。
(ホワイトボードに書きながら)これも人これも理解の仕方が違うところが大きいですが、ドメイン駆動設計は大きく要素が2つあります。1個は戦略的設計というもので、もう1個は戦術的設計です。DDDの本を読んでいても、こういう言葉、こういう分類みたいな感じでいろいろ話されます。
この中で、今日はレイヤー化で3層にするとか、レイヤードアーキテクチャで4層にするという話をしましたが、そういう「レイヤー化はどうする」みたいな話も戦術的設計の一部として出てきます。あとは、ドメインモデルを具体的にどう実装するべきかみたいな話も出てきます。
ただ、ドメインモデルパターンを使えばDDDということではないし、DDDはドメインモデルパターンを使うことを想定した設計のプラクティスではありますが、イコールではないというところですね。
より大事なのは、戦術的設計、実装方式に注目してDDDと呼んでいる例がけっこうあります。戦術的設計だけやっているのは軽量DDDと言われて、場合によってはアンチパターンとも言われます。
個人的には、それでもやってもいいと思うし、別にそれ自体(だけで)もやる価値はあると思うのですが、戦術的設計だけをやるのはあまり良くないよと言われることもあります。
DDDの中で私の理解がすごく大事なのは、戦術的設計も大事ですが、それ以上に戦略的設計と言われるところです。1個はDDDの思想というか、考え方みたいなものです。
DDDはドメイン駆動設計の略ですが、ユビキタス言語を使ってドメインエキスパートと話してドメインモデルを整理していこうとか、そういった「実装上どうだ」だけではなくて、ドメインエキスパートという領域にすごく詳しい人とユビキタス言語、共通言語を使ってちゃんと認識合わせしましょうとか。
その認識合わせをして出来上がったモデルを、そのままコードに落としましょう。それができるように、ちゃんとドメインモデルを隔離したレイヤー化をしましょうという話です。
特にDDDっぽくちゃんとやってるとなると、コードの実装だけじゃなくて、「ドメインエキスパートとの話をちゃんと聞いていますか?」とか「ユビキタス言語と言いますが、そういう言葉の使い方をしていますか?」とか。そちらのほうがむしろ主眼かなと思っています。
あとはサブドメインみたいな言葉や境界づけられたコンテキストが出てきますが、システムでいえばシステムのどこで分割するべきかにも関係してくるような要素も出てきます。
このあたりを全体的に含めてDDDだと私は思っているというか、そういう理解の人もある程度いるはずです。なので、ドメインモデルパターンをやっていたらDDDではなくて、DDDの重要な要素の1つにすぎないという感じです。
逆に、戦術的設計だけやっているのはDDD的にはあまり良くないとされることもある関係です、ということで質問に回答しました。
ちょっと画面共有に戻って最後の話をしていければと思います。質問があれば、どんどんQ&Aにもらえれば、適宜回答します。
ということで、「Controllerに全部書く」からのステップアップを話していこうと思います。
ここまでいろいろ実装の仕方を見てきましたが、具体的に今あるコードを「自分がわりとControllerにいろいろ書いているな」という状態から、どうやってステップアップしていけばいいのかみたいなところを話していこうと思います。
例えばノンフレームワーク、フレームワークを使わなかったり、Node.jsのExpressなどの軽量なフレームワークを使ったりしていて、ControllerにSQLまで書かれている例を考えてみようと思います。最近はORマッパーを使うので、SQLが書かれていることはあまりないかもしれません。
(スライドを示して)例えばControllerにSQLが書かれている(場合)というのは、こんな構成になるわけですね。プレゼンテーション層、ビジネスロジック層、データアクセス層にまたがってControllerがあります。
利用者とやりとりするのもControllerの役割だし、ユースケースの実現とドメインロジックというビジネスロジックのいろいろな要素がControllerの役割だし、データベースでやりとりするSQLも書かれています。
一応データベースと一致する、データベースのテーブルと合わせたデータの入れ物クラス。Entityと言うこともありますが、なんとかRecordみたいなクラスやEntityと言うこともありますがあとUIは、テンプレートエンジンを使っていて、一応分離されている構成も見なくはないですね。この場合、あまり意識してやっているわけではないと思いますが、こういうコードも見かけることはあり得ます。
ここからどう整理していくかはいろいろあるとは思いますが、例えばまずデータアクセス用のクラスを設けてみます。一例として、データベースと1対1で対応するGatewayみたいなものや、なんとかGateway、Player Gatewayみたいなものを設けてみてもいいと思います。
でもこれはControllerの役割が多すぎるんですね。利用者とのやりとりもそうだし、ユースケース、ドメインロジックもそう。
(このように)Controllerの役割が多すぎるので、例えばServiceクラスを設けてみます。プレゼンテーション層とビジネスロジック層をしっかり分離するわけですね。Serviceクラスには、ユースケースとドメインロジックを持たせます。
こうなってくると一応整理されている、よく見るコードになってきているイメージです。この間にDTOとかなにかは多少いるかもしれませんが、ざっくり、ControllerとServiceとデータアクセス用のなんとかGateway、Gatewayの名前はいろいろありますが、こういう構成はわりと見かけます。
ただ、この構成はServiceの役割が多すぎます。そして、複数サービスで似たドメインロジックを実装したい時に、コードが重複しやすいです。似たというか、まったく同じドメインロジックを実装したい時に、重複すべきではないドメインロジックがサービス間で重複しやすい構成だったりします。
そこでドメインロジックをModelに持たせると、Serviceの見通しが良くなりやすいです。Serviceがユースケースもドメインロジックも持っていると、Serviceのメソッドが100行とかにもぜんぜんなるし、普通に30行、50行とかになって見通しが悪くなっていきます。
結局はドメインロジックの設計次第なところもありますが、ドメインロジックをドメインモデルにしっかり持たせて、そこをしっかり整理していけば、ある程度コードも見通しが良くなっていくかなと思います。
(スライドを示して)さらに加えて、これはビジネスロジック層と書いてありますが、ドメイン層をアプリケーション層、ドメイン層と分けたり、Repositoryパターンを導入したりということも考えられるとは思います。そうすると、まさに途中で説明したようなアーキテクチャになっていくイメージですね。
ここでのポイントは、クラスごとの役割分担だと思います。難しい表現はいろいろありますが、役割分担はけっこうわかりやすい言い方かなと個人的に思っていて、クラスごとにどんな役割を持たせるかがすごく大事だと思います。
これでは1個1個のクラスの役割が、「このクラスの役割は何ですか?」「このクラスは、テーブルと一致するデータの入れ物です」「このクラスの役割は、ユースケースです」と、一言で説明したりがすごくしやすいと思います。
こういう役割分担がすごく重要だと思います。ここに出している役割はあくまで例であって、例えばこれ以外にも表示用の変換が必要な場合がよくあると思います。
その表示用の変換は、どこかの既存のクラスに入れてしまうこともあるし、「Presenterというクラスを作って、そこに書きましょう」とすることもよくあります。こんなやり方が1つあると思います。
(次回に続く)
関連タグ:
“1つの独立して動く要素”の内部を整理し直す 「改めて整理するアプリケーション設計の基本」で伝えたいこと
アプリケーションアーキテクチャ理解に必要な“3層構造” プレゼンテーション層・ビジネスロジック層・データアクセス層それぞれの役割
3層アーキテクチャで最も謎な「ビジネスロジック層」 “システムのコア”をゲーム「リバーシ」で解説
「ビジネスロジックの処理は2つに分類すると整理しやすい」 4つの例から考える、プレゼンテーション層・データアクセス層の見分け方
ビジネスロジック層内部の2つの実装パターンを比較 選択時に考えたい、アプリケーション設計の観点
「クラスごとの役割を明確化すること」がポイント アプリケーション設計におけるドメインロジックの分離法
重要なのは「基本を押さえ、適したものを採用すること」 “本来の役割”を押さえたアプリケーション設計
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05