Data Mapperをめぐる二つの世界観
BEAR.Sunday Advent Calendar 4日目は架空の人物による架空のディスカッションを記事にしました。
はじめに
二人の登場人物を紹介します。
koriym は、フレームワークの開発者であり、オブジェクト指向設計、とりわけ「関心の分離」や「純粋なドメインモデル(Persistence Ignorance)」にこだわりを持つアーキテクト。
たつきち は、Symfonyという実用的なフレームワークのエコシステムの中で、現実的な開発効率と保守性のバランスを取る「現場のエンジニア」としての視点を持っています。
⚠️ 重要: この議論の二人は実在の人物と一切関係がありません。ご注意ください。
この「貧血モデル(Anemic Domain Model)」を巡る議論は、ソフトウェアアーキテクチャにおける永遠のテーマの一つです。この架空の二人のキャラクターとスタンスを踏まえ、その後のディスカッションを創作(シミュレーション)してみます。
背景:PHPカンファレンスでの発表
この議論は、PHPカンファレンスで たつきち がDoctrine ORMについて発表した後に始まりました。
発表の要旨はこうでした。Symfonyの開発において、Doctrine ORMを採用しているが、実際にはエンティティにビジネスロジックを持たせない「貧血モデル」として使っている。それは本来のData Mapperパターンの思想からすれば邪道かもしれない。言ってみれば「高級なActive Record」のような使い方だ。しかし、それでもDoctrineを選ぶ理由がある。それは テストのしやすさ だ、と。
この発表を聞いた koriym が、懇親会で声をかけたところから、以下のディスカッションが始まります。
ラウンド0:「貧血」の向こう側にあるもの
koriym:
「テスト、ですか。もう少し詳しく聞かせてください。もしモデルがロジックを持たない単なるデータ構造(貧血モデル)なら、テスト対象は主に『サービスレイヤー』になりますよね。データの出し入れだけのモデルなら、Eloquentでもモックすればテストは書けるはずです。Doctrineであることの決定的な差はどこに生まれるんでしょう?」
たつきち:
「はい、おっしゃる通りロジックはServiceに寄ります。ただ、Eloquent(Active Record)の場合、モデル自体がDB接続を持ち、静的メソッド(User::find()など)への依存がコードの至る所に分散しがちです。これをテスト時にモックするのは、LaravelのFacade機能などを使えば可能ですが、言語レベルで見ると少しマジックに頼ることになります。
一方でDoctrineは、データ(Entity)と永続化操作(Repository/EntityManager)が明確に分かれています。Serviceクラスに『Repositoryインターフェース』をDI(依存注入)さえすれば、テスト時はインメモリの配列を使ったRepositoryに差し替えるだけで、DBなしの高速なユニットテストが成立します。この『設計の素直さ』がテストの書きやすさに直結するんです。」
koriym:
「なるほど。つまり、Doctrineを採用する最大のメリットは、Data Mapperパターンそのものというより、それに付随する 『Repositoryパターンによる依存性の解決』 にある、というわけですね。
ただ、そこで疑問が残ります。もしエンティティがただの『入れ物』であり、ロジックがサービスに書かれるなら、それはオブジェクト指向というより、手続き型プログラミング(トランザクションスクリプト)に近い形になりませんか?」
たつきち:
「痛いところを突かれますね(笑)。正直に言えば、現代のWeb開発、特にSymfonyでフォームやシリアライザーをフル活用する開発スタイルは、 『型安全でリッチなトランザクションスクリプト』 になっている側面は否めません。
ですが、僕はそれを悪いことだとは思っていないんです。POPO(Plain Old PHP Object)であるエンティティは、特定の親クラスを継承していないため、副作用を心配せずにどこへでも持ち運べます。これが『認知負荷の低さ』につながります。」
koriym:
「ふむ、 『副作用のないデータ構造』 としてのPOPOの価値ですね。Active Recordは便利ですが、モデルを渡すたびに『ここでsave()されたらどうしよう』という不安がつきまといます。Doctrineのエンティティは、EntityManagerを通さない限りDBに反映されない。その『意図しない書き込みへの安全性(Immutabilityに近い安心感)』も、テストや保守におけるメリットと言えそうですね。」
たつきち:
「まさにそうです! Eloquentを使っていた頃は、どこでSQLが走っているか疑心暗鬼になることがありました。Doctrineは『Unit of Work』が変更を監視し、最後に明示的にflushするまでは何も起きません。たとえ貧血モデルであっても、この 『永続化のタイミングを完全に制御できる』 という点こそが、大規模なアプリケーションで事故を防ぐ最後の砦になるんです。」
koriym:
「面白いですね。本来、Data Mapperは『ドメインロジックをインフラ(DB)から守る』ためにあるものですが、たつきちさんの使い方は 『データを副作用から守る』 ためにData Mapperの仕組みを利用している。理想的なドメイン駆動設計(DDD)ではないかもしれないが、フレームワークのエコシステムと整合性を取りながら、堅牢さを確保する『現実解としてのDoctrine』ということですね。」
たつきち:
「はい。SymfonyのFormコンポーネントがエンティティのゲッター/セッターを直接叩く仕様である以上、そこにあらがってリッチなドメインモデルを無理に導入するより、フレームワークのレールに乗った上で、DBレイヤーの抽象化の恩恵だけを最大限受けるのが、チーム開発では最もコストパフォーマンスが良いという判断です。」
koriym:
「なるほど。純粋なオブジェクト指向の観点からは『高級なActive Record』に見えますが、その『高級さ(抽象化と安全性)』には、確かにコストを払うだけの明確な実利がありそうですね。特に、PHPという言語が持つ『リクエストごとに状態がリセットされる』特性と、Unit of Workの相性は良い。貧血であることを恐れずに、その特性を道具として使い倒す姿勢、勉強になります。」
ディスカッションの分析
この創作議論では、以下の対立軸と合意点が浮かび上がります。
-
理想 vs 現実:
- koriym: Data Mapperならドメインロジックをカプセル化すべきでは?(本来のOOP/DDDの視点)
- たつきち: フレームワーク(Symfony)の仕様に合わせると貧血にならざるを得ないが、それでもメリットはある。(プラグマティズム)
-
テスト容易性の正体:
- Doctrineのメリットは「モデルの純粋さ」そのものより、「RepositoryパターンによるDIのしやすさ」と「DB操作(副作用)の分離」にあるという点での合意。
-
Active Recordとの差別化:
- 単なるDB操作ライブラリとしてではなく、 「いつSQLが発行されるか制御できる安心感(Unit of Work)」 と 「特定の親クラスに依存しないデータのポータビリティ(POPO)」 に価値を見出している点。
このように、「貧血モデル=悪」と切り捨てるのではなく、 「なぜSymfony環境下では貧血モデル+Doctrineが合理的解となるのか」 を言語化する、非常に建設的で興味深い議論になるのではないかと想像します。
ラウンド1:理想と現実の「インピーダンスミスマッチ」
koriym:
「たつきちさんの合理的な判断は理解できました。ただ、少し矛盾を感じませんか?Doctrineのメンテナ、特にMarco Pivetta(Ocramius)や、DDDのエリック・エヴァンス、そしてマーティン・ファウラー。彼らは一貫して『貧血ドメインモデル(Anemic Domain Model)』をアンチパターンとし、Data Mapperはドメインロジックをカプセル化するためにあると説いています。しかし、Symfonyの文化圏——特にフォームやシリアライザーの実装——は、その教えに逆行するように、エンティティを単なる『データの袋』として扱うことを推奨しているように見えます。」
たつきち:
「そうですね、Symfonyのドキュメント通りに作れば、自然と貧血モデルになります。思想と実装の間に乖離があるのは事実です。一方でDoctrineチームはリッチモデルを推していますが」
koriym:
「ええ。そこで私が興味深いのは、 『なぜActive Recordの手軽さを捨ててまで、Data Mapperという重厚な装備を選んだのか』 という点です。もしエンティティがただのデータ構造なら、Doctrineの学習コストや、ハイドレーション(Hydration)のオーバーヘッドは、得られるメリットに対して支払うコストとして高すぎませんか?言ってみれば、 『フェラーリのエンジン(Doctrine)を積んで、近所のスーパーに買い物に行く(CRUDアプリを作る)』 ような、ある種の贅沢さと非効率さを感じるのです。」
たつきち:
「(苦笑して)痛いところを突きますね。確かに『オーバースペック』だという批判は甘んじて受け入れます。ただ、僕たちにとってDoctrineは、もはや『ドメインを隔離するための防壁』ではなく、 『Symfonyというエコシステムを円滑に回すための標準規格』 になってしまっているんです。
コストが高いことは認めますが、Symfonyを選んだ時点でDoctrineに乗っかるのが、チーム開発において最も『共通言語化』しやすい。思想的な正しさよりも、エコシステムのレールに乗る『政治的な正しさ』を選んでいる側面はあります。」
koriym:
「 『エコシステムのレール』 ……なるほど、それが答えですか。本来、Data Mapperはデータベースの都合からドメインを守るためのものでしたが、現代のSymfony開発においては、フレームワークの都合(生産性や標準化)のために、逆にドメインモデルの純粋性が犠牲になっている。つまり、たつきちさんは『Doctrineを使っている』のではなく、 『Symfonyの一部としてのDoctrine風DBレイヤー』 を使っている。そう定義すれば、すべての辻褄が合いますね。」
たつきち:
「ぐうの音も出ません(笑)。でも、その通りです。僕は『Doctrine使い』ではなく、あくまで『Symfony使い』として、このツールを見ているんだと思います。」
koriym:
「いえ、責めているわけではありませんよ。むしろ感心しています。理論的な『正解』と、現場の『最適解』が食い違ったとき、多くのエンジニアは悩みますが、たつきちさんは 『テストと安全性』という実利 を確保した上で、その矛盾を飲み込んで開発を進めている。
その割り切りこそが、現代のWeb開発のリアリズムなのかもしれませんね。」
ディスカッションの分析
このやりとりでは、以下のような深掘りがなされました。
-
koriymのクールな指摘:
- 「思想的権威(Fowler/Pivetta)」と「現場の実装(Symfony)」の矛盾を指摘。
- 「コスト対効果(ROI)」の観点から、貧血モデルにData Mapperを使う非効率さを指摘(フェラーリの比喩)。
-
たつきちの受容:
- 反論するのではなく、「エコシステムの標準規格」としての採用であることを認める。
- 「Doctrine使い」ではなく「Symfony使い」であるというアイデンティティの再定義。
-
結論:
- これは「技術的な優劣」の話ではなく、「どのコンテキスト(純粋なOOP vs フレームワークの生産性)」を優先するかという 価値観のトレードオフ であるという着地点。
この続きとして、「じゃあ、本当にリッチなドメインモデルが必要になる境界線はどこか?(複雑さがどこを超えたらSymfony流を捨てるべきか)」という議論にも繋がります。
ラウンド2:V12エンジンと迷えるドライバーたち
koriym:
「それにしても、Doctrineというのは本当に『モンスター』ですよね。PHPの歴史の中で、これほど長くメンテナンスされ、複雑怪奇かつ精緻に組み上げられたライブラリは他にない。まさに、フェラーリのV12エンジンのようなものです。そのエンジニアリングの極致には、純粋に畏敬の念を抱きます。」
たつきち:
「ええ、中身のコードを追うたびに、その複雑さと抽象化のレベルには圧倒されます。」
koriym:
「だからこそ、もったいないとも思うし、同時に不思議でもあるんです。V12エンジン(Doctrine本来の推奨実装)は、リッチなドメインモデルを駆動させるために設計されています。しかし、Symfonyという車体(フレームワーク)に乗せた途端、多くの開発者はアクセルを全開には踏まない。
……そこで一つ、以前から気になっていることがあります。 『結局、ビジネスロジックはどこに書くべきか?』 という問題です。」
たつきち:
「ああ……(苦笑)。それはもう、僕らSymfonyユーザーが10年以上議論し続けている、終わりのないテーマですね。」
koriym:
「コントローラーは薄くしろと言われますが、 『じゃあ溢れたロジックはどこへ?』 という問いに対する、コミュニティとしての絶対的な合意(Consensus)が存在しませんよね。『Serviceクラスにとりあえず全部書く』という現場もあれば、『いや、Command Busだ』『Actionクラスだ』と、毎回のようにアーキテクチャ論争が起きている。」
たつきち:
「耳が痛いですね。Doctrineのエンティティを貧血にしてしまった以上、ロジックは行き場を失って、結局『〇〇Service』という名前のクラスに手続き的に記述されることが多いのが現実です。自由度が高いと言えば聞こえはいいですが、実際のところは、『標準の制約がないから、毎回自分たちでレールを敷き直している』 だけなのかもしれません。」
koriym:
「ええ、それが私の言う『興味深い矛盾』です。Doctrineという世界最高峰のData Mapperを持っていながら、使い方はトランザクションスクリプトに近い。フェラーリのエンジンを積んでいるのに、ナビ(フレームワークの規約)が目的地を示さないから、ドライバーたちは交差点のたびに『どっちに曲がる?』と会議をしている。だからこそ、アーキテクチャをテーマにしたセッションが、毎年のように披露され、多くの聴衆を集めるのでしょうね。」
たつきち:
「確かに。僕たちは『Symfony流(便利なエコシステム)』と『Doctrine推奨(あるべきOOP)』の間で、常にバランス調整をしているんだと思います。完全にSymfony流に倒して貧血にするか、少しDoctrine推奨に寄せてロジックを凝集させるか。そのスライダーをどこに合わせるかが、アーキテクトの腕の見せ所になっている……というのは、言い訳がましいでしょうか?」
koriym:
「いいえ、それが偽らざる実感なのでしょう。正解がないのではなく、 『パワフルすぎる道具(Doctrine)と、寛容すぎる環境(Symfony)』 の組み合わせが、必然的にその議論を生み出し続けている。そう考えると、たつきちさんがスライドの最後で『テスト』という実利に落とし込んだのは、その終わらない議論に一つの杭を打つ、非常に現実的なアプローチだったと言えそうですね。」
ディスカッションの分析
このラウンドでは、以下の点が議論されました。
-
Doctrineへの畏敬と疑問:
- koriymはDoctrineを「V12エンジン」「モンスター」と称え、その工芸的な凄みを認めつつも、その性能がフルに活かされていない現状を指摘。
-
「ロジックの置き場所」問題:
- Symfonyコミュニティが10年以上解決できていない永遠のテーマ。Service、Command Bus、Actionクラス……標準がないからこそ、毎回レールを敷き直している現実。
-
フェラーリとナビの比喩:
- パワフルなエンジン(Doctrine)があっても、ナビ(フレームワークの規約)が目的地を示さなければ、ドライバーは迷い続ける。自由度の高さが、逆に議論を生み出し続ける構造になっている。
ラウンド3:モデルってなに?
koriym:
「しかしMVCフレームワークなのに肝心の"M"の合意がないのはおかしな話ですよね。そもそもモデルって何モデルですか?ドメインモデル?データモデル?パーシステントモデル? トリグヴェ・リーンスカウクのオリジナルのMVCのモデルは明快で『メンタルモデル』でしたが」
たつきち:
「メンタルモデル……。ユーザーの頭の中にある概念そのもの、ですね。ですが、今のWebフレームワークの文脈で『モデル』と言えば、ほぼ間違いなく 『データベースのテーブル定義(Active RecordやEntity)』 を指します。
実際、LaravelならEloquent Modelですし、Symfonyなら……そもそもディレクトリ構造に『Model』という名前すらなく、『Entity』と『Repository』があるだけです。」
koriym:
「そこが悲劇の始まりです。本来、モデルとは 『アプリケーションそのもの』 だったはずです。ユーザーの意図を受け取り、計算し、判断を下す『脳』の部分です。データベースへの読み書きなんて、モデルが持つ機能のほんの一部(永続化)に過ぎない。
しかし、フレームワークが『モデル=DBアクセス』と定義してしまったせいで、アプリケーションの『脳』を入れる場所がなくなってしまった。」
たつきち:
「……あ、なるほど。だから僕たちは、行き場をなくした『脳(ロジック)』を置くために、後付けで Service ディレクトリを作ったり、UseCase を切ったりしているわけですね。
フレームワークが用意した『M』が、ただの『データ保管係』になってしまったから。」
koriym:
「その通りです。MVCの『M』が空洞化し、データ構造(Entity)だけが残った。その空洞を埋めるために、みんな必死で名前を探しているんです。ある人はそれを『Service』と呼び、ある人は『Interactor』と呼び、そしてある人は……」
たつきち:
「…… 『軽量DDD』 と呼ぶ、ということですか。」
koriym:
「ええ。話が繋がりましたね。」
ラウンド4:それは「軽量」なのか、それとも「虚構」なのか
koriym:
「さて、先ほど『ロジックの置き場所が決まらない』という話をしましたが、その文脈でよく耳にする言葉がありますね。 『軽量DDD(Lightweight DDD)』 という言葉です。
SymfonyやLaravelのコミュニティでは、DoctrineのようなORMを使い、Repositoryパターンを導入し、Serviceクラスにロジックを集めるスタイルを、こう呼んで正当化する傾向があります。これについて、どう思われますか?」
たつきち:
「……(苦笑)。また際どいところに来ましたね。正直に言えば、僕もその言葉を使うことはあります。ガチガチのDDDをやるコストはないけれど、MVCのFat Controllerは避けたい。その中間の『ちょうどいい設計』を指す便利なラベルとして機能しているのは事実です。」
koriym:
「便利なラベル、ですか。私の目には、それが 『奇妙な着地点(Strange Landing Point)』 に見えるのです。DDDの本質は、ドメインエキスパートと対話し、ビジネスの深い洞察をモデルに反映させることにあります。しかし『軽量DDD』と呼ばれるコードの多くは、単に『レイヤー分けされたトランザクションスクリプト』です。Entityはゲッター/セッターだらけの貧血モデル。Repositoryはただのクエリビルダのラッパー。Serviceは手続きの寄せ集め。 これなら、素直に『レイヤードアーキテクチャ』と呼べばいい。なぜわざわざ『DDD』という看板を借りる必要があるのでしょうか?」
たつきち:
「それは……やはり『共通言語』が欲しいからだと思います。チーム開発において『このロジックはServiceへ』『DB操作はRepositoryへ』という指針があるだけで、コードの秩序は保たれます。たとえそれが本質的なDDDでなかったとしても、『DDD風のディレクトリ構成』があることで、新人エンジニアでも『どこに何を書くべきか』がなんとなく分かる。その 『整頓のルール』 として、軽量DDDという名のスタイルが定着してしまったんだと思います。」
koriym:
「なるほど。つまり、本来は『複雑さを解決する技術』であるDDDを、 『散らかったコードを整理する収納術』 として消費しているわけですね。」
たつきち:
「うっ……『収納術』と言われると反論できません。ですが、フェラーリ(Doctrine)のエンジンルームが整理整頓されていることは、メンテナンスにおいて重要です。たとえ最高速を出して走るわけではなくても。」
koriym:
「ええ、整理整頓を否定はしません。ただ、私が危惧するのは、その『看板の重さ』です。『私たちはDDDをやっている(軽量だけど)』と宣言した瞬間、開発者は『思考停止』に陥りやすい。本来なら『このモデルは本当にビジネスを表現しているか?』と問い続けるべきところを、『RepositoryとServiceに分けたからOK』と満足してしまう。それは軽量なDDDではなく、 『重量級のMVC(Heavyweight MVC)』 と呼ぶべきではありませんか? ファイル数とレイヤーだけが増え、複雑さは変わっていないのですから。」
たつきち:
「『重量級のMVC』……。その表現は強烈ですね。
確かに、Doctrineを使ってEntityやRepositoryを量産することで、開発コスト(重量)は増しています。それに見合うだけの『ドメインの表現力』が得られていないなら、ただ重くなっただけと言われても仕方がない。」
koriym:
「そうです。フェラーリを買って、わざわざ荷台をつけて引越しの荷物を運んでいるようなちぐはぐさを感じます。もし『テスト容易性』と『整理整頓』が目的なら、DDDという言葉を使わずに、堂々と『テスト可能なトランザクションスクリプト』と名乗るほうが、アーキテクチャとしては誠実で、かつクールだと私は思いますよ。」
たつきち:
「『テスト可能なトランザクションスクリプト』。……確かに、今日の僕の発表の結論(貧血モデル+Doctrine=テストしやすい)は、まさにそれですね。DDDへの憧れを捨てて、等身大の自分たちの設計を正しく名付ける。それが『変な着地点』から脱出する第一歩なのかもしれません。」
ディスカッションの分析
この続きの議論では、以下の点が浮き彫りになります。
-
「軽量DDD」への批判:
- koriymは、これを「収納術」として消費されていると分析。
- 最大の問題は、レイヤーを分けることが目的化し、 「ビジネスの洞察」というDDDの本質が抜け落ちること による思考停止。
-
「重量級MVC」というパワーワード:
- 「軽量DDD」の実態は、単にファイル数と間接層が増えただけのMVCであることを指摘。
- Doctrineの複雑さ(重量)を背負いながら、DDDのメリット(軽量な変更耐性)を享受できていない矛盾を突いています。
-
誠実な命名:
- 「DDD」というブランドに頼らず、実態(テスト可能なトランザクションスクリプト)に即した名前で呼ぶべきだという提言。
- これにより、たつきちさんの「テスト重視」という姿勢が、実はDDDの亜種としてではなく、独自のプラグマティックな戦略として再評価されます。
ファイナルラウンド:設計者の言葉、製造者の言葉
koriym:
「たつきちさんのお話、非常に合理的で興味深かったです。ただ、少しだけ不思議な感覚がありました。私の認識では、Data Mapperというのは本来、データベースの都合から『ドメイン』を守るための……いわば防波堤のようなパターンだと思っていたんです。でも、今日のお話を聞いていると、少し役割が違って聞こえました。ドメインを隔離するためというよりは、何かこう……もっと実務的な、 『製造』のための規格 として機能しているのかな、と。」
たつきち:
「『製造』の規格、ですか?」
koriym:
「ええ。たとえば、自動車を作る工場のようなイメージです。
Entityという規格化された部品があり、Repositoryというラインがある。そこにデータを流せば、均質な製品(機能)が効率よく出来上がる。
そこでは『この部品の意味は何か?』と毎回悩みながら設計する(Design)というよりは、決められた図面通りに正確に組み立てる(Manufacture)行為に近い印象を受けました。」
たつきち:
「ああ……なるほど。その感覚は否定できません。確かに、僕たちにとってDoctrineは『悩むための道具』というよりは、『迷わず作るための道具』です。エヴァンスやファウラーが言ったような『ドメインの探求』が理想なのは分かります。でも、実際の現場では、いちいち立ち止まって哲学的な議論をする時間よりも、仕様書通りの機能を、納期までにバグなく『生産』することのほうが、ずっと切実な価値だったりするんです。」
koriym:
「やはり、そうですか。私がエヴァンスの青い本(DDD本)で読んだData Mapperは、コードの中にビジネスの形を彫刻するための ノミ でした。ですが、今のSymfonyの現場で使われているのは、同じ名前でも、高性能な プレス機 に近いのかもしれませんね。」
たつきち:
「プレス機、言い得て妙ですね(笑)。味気ないと言われればそれまでですが、そのプレス機のおかげで、僕たちは一定の品質を保ちながら、ものすごいスピードでWebサービスを世に送り出せています。それが『設計』をサボっていることになるのか、それとも現代的な『製造』の最適化なのか……。」
koriym:
「サボっているわけではないでしょう。ただ、見ているゴールが違う。Data Mapperは本来『設計行為』を支える道具ですが、たつきちさんの現場では、それは『製造行為』として最適化されている。だから、ドメインモデルが貧血であっても問題ない。なぜなら、製造ラインにおいて、部品が勝手に振る舞いを変えたり、主張を持ったりするのは、かえって邪魔だからです。」
たつきち:
「そうですね、僕は『速度』のために貧血モデルを選んでいると言ってきましたが、本当は 『手間を省いていた』 だけなのかもしれません。もし部品(Entity)が『こんなデータは受け入れられない』という強い主張(ドメインロジック)を持っていたら、SymfonyのFormやSerializerといった自動化された製造ラインは、そこで停止してしまいます。
ラインを止めずに高速で回し続けるためには、どんなデータでも文句を言わずに受け入れる、従順な部品である必要がある。僕は『扱いやすい部品』だと思っていましたが、それは単に 『フレームワーク(機械)の都合に合わせた設計』を受け入れていた側面はあると思います。自分ですべき『ビジネスの設計』を、フレームワークの流儀に丸投げしていたところはあると思います。
koriym:
「その便利さを引き受けた代償として、ドメインの主導権が失われた。だから『貧血』になったのは結果論に過ぎず、本質は『ビジネスを知らないフレームワークが、アプリケーションを設計してしまっている』点にある。あとで負債が顕在化するのは、その借り物の設計と、現実のビジネスのズレが表面化するからでしょう。」
たつきち:
「腑に落ちました。ある意味『設計者』であることを放棄して、単に『フレームワーク利用者』になることで、その負債を背負い込んでいたんですね。しかしそれを引き受けた事で得られたものも少なくないし、それが今の現場感です。」
koriym:
「ええ。ファウラーたちが言うことは、間違いなく真理です。ですが、彼らの言葉は設計者に向けたものであって、フレームワーク利用者に向けたマニュアルではなかった。私たちが感じるズレの正体は、きっとそこにあったんですね。」
たつきち:
「確かに設計者と利用者とそれぞれ違ったマインドセットがありますね。僕も、今日のカンファレンスで発表した内容を、少し振り返ってみようと思います。『貧血モデルでテストできる』という結論は変わらないけれど、『なぜ貧血なのか』 の部分に、もう少し自覚的になれる気がする。」
koriym:
「それは素晴らしいことですね。私も、たつきちさんとの対話で、 『なぜ現場はそうなるのか』 という構造への理解が深まりました。」
たつきち:
「お互いに、問いが深まりましたね。」
koriym:
「ええ。良いカンファレンスでした。」
⚠️ 重要: この議論はAIで生成された架空のものであり、登場する二人は実在の人物と一切関係がありません。
対談いかがだったでしょうか。この記事は"ついにたどりついた正解"や理想論vs現状追認ではありません。いまだ確たる答えのない深淵な問いです。見る人見る角度によって様々な見え方をするはずです。
たつきち:
「いやいや、こんな事はないです!これは言い過ぎ!!」
koriym:
「ではこうですか?」
koriym:
「そもそもオブジェクト指向どこに...」
(続く)
編集後記
特定のコンテキストを与えて、AIに仮想対談をさせるという企画で「MVCフレームワークの問いの深淵」を、Doctrine ORM(Data Mapper)の現実を元に作成してみました。
これはなかなか対談のトーンをつくるのが難しく、特にこの二者ならドメインモデル派が貧血モデル派に「正しさ」を一方的に説く形になったり、あるいは「貧血派」が議論を品質 VS 速度のチープな二項対立に持ち込んだりして面白くありません。かといって、「みんな違ってみんないい」という予定調和は、この議論の熱量にそぐわず、やってみましたが、色々言ってるようで何も言ってない感じになってしまいボツにしました。
結局、議論に出てくる「たつきち」さんを、「現実解を説いている自信を持ちながら、どこかあるべき姿を実践できていない後ろめたさを感じる」ような設定にしました。なので答えに窮しているのは意図的なもので、いわば"嘘"です。
もし彼が開き直って「動けばいいんだよ」と言えば議論は平行線ですし、逆にすぐに改心して「明日からDDDやります」と言えば嘘くさくなります。「Symfony使い」としてのプライドと、エンジニアとしての知的誠実さの間で揺れるキャラクターとすることで、読者の心情を代弁し、この深淵な問いの構造を考えるきっかけになるのでは思いました。


