はじめに
みなさんどうも、美味しい鯖缶を目指しているものです。
久々にこのシリーズを書いていこうと思います。
待ちくたびれていた方も多いと思います(累計いいね数0)
今回は私が最近ハマってるアーキテクチャの設計思想を深ぼるところなので気合い入れてやっていこうとも思います。
ちなみにですが私はレイヤ化アーキテクチャ呼び派閥です。
別にレイヤードアーキテクチャと呼んでもいいのですが、エリックエヴァンスに準拠してレイヤー化とします笑
モデル駆動設計
まずレイヤ化アーキテクチャに入る前にモデル駆動設計というレイヤーかアーキテクチャをより抽象化した上位思想について見てみます。
本文引用で
-
多くの設計の方法論では「ビジネスドメインを分析した結果のモデル」(分析モデル)が主張される。
-
しかし、分析モデルはビジネスドメインだけを考慮したものであり、実装も含め分析したものではない。
-
これらで実装に向けての設計を行うと、新しい抽象概念を考えなくてはいけなくなる
これらから言えることは、非常に分析の分に対する設計の質などの費用対効果が薄く、ざっくり言えばコスパが悪い。
そこで思想的に『ユビキタス言語で支えドメインと実装両方の目的に使える単一モデルを要求すること』
が非常に大事になります。
これがモデル駆動設計の最大の目的です。
モデル駆動設計のポイント
- モデルが実装を支えながら、ドメインを抽象化する
- モデルと設計の対応関係
- モデリングパラダイムがモデルに含まれる概念と直接的に類似したものを生成されるサービスを利用
という点がある
モデリングパラダイムとは
ざっくりと「モデルを組み立てるための枠組み」という認識です。
以下の記事よりお言葉お借りしました。
こちらの記事に詳しく書かれていますので読んでみると非常に参考になります。
また、今回の記事は思想的には、オブジェクト指向に関するモデリングパラダイムを扱います。
ここまでで色々とモデル駆動設計のをざっくりと理解するため解説を書きましたが、本の内容的にはまだまだだまだ続いています。
内容は割愛しますが、これらにおける汎用的なプロセスを書いてくれています。
レイヤ化アーキテクチャ
はてさて本題に入ります。
まず前提として
オブジェクト指向型プログラミングは
- ビジネスロジックと実装が混ざる可能性
- 混ざるとコードが複雑になる
- 混ざった結果、ビジネスロジックの変更に対応しにくくなる
(具体例として:UIを変更したらビジネスロジックを変更なくてはいけない時)
などの問題点があります。
では、本質的にレイヤ化アーキテクチャとはなんなのだろうかという点です。
先ほどの章や上記の内容を討論するうちに一つのアプローチが生まれます。
「ドメインオブジェクトをシステムの機能と疎結合にする」という考え方です。
ではどのように切り離していくのか...
一旦イメージは以下のようになります。

※ 実際はコンポジションや双方向の関係を含む場合もあります、あくまでイメージです。
本質的な要素はレイヤ内の要素は一つ下にあるレイヤの要素にしか依存しないです。
また、後述しますが「上のレイヤへのコミュニケーション」はなんらかの間接的な仕組みを介さなければならない。
という本質的な原則があります。
4つの各レイヤは概念的に以下のように定義されたものになります。
| レイヤ名 | 定義 |
|---|---|
| ユーザーインターフェイス(UI)層またはプレゼンテーション層 | ユーザーに情報を表示して、コマンドを解釈する責務。外部アクターは人間以外も指すことがありコンピュータシステムの場合もある。 |
| アプリケーション層 | ソフトが行う仕事を定義、表現力豊かなドメインオブジェクトが問題を解決で切るように導く(ビジネスにとっての問題か他システムのアプリケーション層の相互関係か)また、このレイヤは薄く保たれる。 |
| ドメイン層(モデル層) | ビジネスの概念と、ビジネスが置かれた状況に関する情報、およびビジネスルールを表す責務を負う。ここがビジネスソフトウェアの核心部分 |
| インフラストラクチャ層 | 上位レイヤーを支える一般的な技術的機能を提供。例えば:ウィジェット描画、ドメインのための永続化、メッセージ送信など |
もう少しざっくり言えば
UI層
- ユーザーに情報を表示したりとかコマンド的なのを解釈させる責務
アプリケーション層
- バリデーションなどドメインが問題解決できるようにするような責務
ドメイン層
- アプリの中軸的な部分、重要な情報はここに
インフラストラクチャ層
- 一般的に技術的な実装を支える部分
かなり抽象的なので後ほど例を交えながら見ていきます。
結局、このようにレイヤに分ける理由は「ドメインモデルを表現するという責務に専念し、本質的なビジネスの知識をとらえてそれを機能させるため」です
ここで余談ですが、そもそもの定義は抽象的なので決定的にこれをやれというフレームワークは存在しないのですね...チームによって一番いい形を作るのが最優先だと思います。
なので、人によって本当に解釈は変わりそれは組織によってもかなり変わるなぁとも思いました。
まとめとその他
レイヤ化アーキテクチャの本質は ドメインオブジェクトをシステムの機能と疎結合にするという点だということがわかりました。
しかしながら、分離することは非常に難しい場合もあります。
練度の低いチームがドメイン駆動設計、ましてやモデル駆動設計をすると
「UI層にビジネスロジックが混ざり、関係データベースがリポジトリになる」
というケース生みます。
これを本書では、「利口なUI」と呼んでいてアンチパターンとされています。
練度が低いチームが無理やりDDDをやると上記のようになりDDDの本質から逸れたことをやってしまうので、無理にしないほうがいいとも言われています。
そこで、そのアンチパターンとモデル駆動設計(今回だとレイヤ化アーキテクチャ)の間のトランザクションスクリプトを採用するといいとも言われています。
(UIをアプリケーションからは分離するが、オブジェクトモデルは提供しない)
これであればDDDを支えられるだろうとも言われています。
最終的にこれらから言えることは、しっかりとDDDをやりたいのであれば、各分野の専門家をそれなりに集めて利口なUIになるケースを避けるような開発形態をとることが重要だということです。