これはずいぶん昔からあるアンチパターンのひとつですが、今になって台頭してきているようです。 Eric Evans と話したのですが、彼も、それがだんだんポピュラーになってきていることに気づいていました。 私たちほど大の「真ドメインモデル」推進者としてみれば、ちょっとうれしくありません。

ドメインモデル貧血症の基本的な症状は、一見、それが本物のドメインモデルに見えるという点です。オブジェクトがいくつかあり、それらはドメイン空間にある名詞から名前をつけられています。それから、オブジェクト同士がしっかりとしたリレーションで結びついており、本物のドメインモデルと同じような構造を持っているのです。 ただし、オブジェクトの振る舞いを見れば違いが分かります。それらのオブジェクトにはわずかな振る舞いしかない、ということに気づくと思います。 ドメインのロジックをドメインオブジェクトの中に入れないという設計ルールに従っているのでしょう。その代わり、すべてのドメインロジックを含むサービスオブジェクト群が存在しているのです。 こういったサービスはドメインモデルの上位に居座り、データのためだけにドメインモデルを使うのです。

このアンチパターンが根本的に怖いのは、オブジェクト指向設計の基本概念(データと処理を一緒にする)の真逆だということです。 ドメインモデル貧血症とは、単なる手続き型設計のことなのです。まさに、私(そしてEric)のようなオブジェクト信望者が、Smalltalkの初期からずーーーーーっと戦ってきたもの、そのものなのです。 さらに困ったことに、貧血オブジェクト(Anemic Object) が本物のオブジェクトだと思っているひとがたくさんいます。 つまり、オブジェクト指向設計が何たるかをまったく分かっていないということなんです。

現在のオブジェクト指向純粋主義は全く素晴らしいことですが、この貧血(anemia)については、基本的な議論をもっとすべきのようです。 ドメインモデル貧血症問題の本質は、ドメインモデルのベネフィットを何も得ず、コストだけをすべて被ってしまうという点です。 まず最初のコストは、データベースにマッピングする煩わしさです。大抵の場合、この作業はO/Rマッピングのレイヤーが行うべきことです。強力なオブジェクト指向技術を持っていて、複雑なロジックを整理できるのであれば、これはやり甲斐があります。 とはいえ、すべての振る舞いをサービスに押し込むと、どうしても トランザクションスクリプト になってしまいます。これでは、ドメインモデルのもたらすメリットを失います。

多くのOOエキスパートたちが、処理を行うレイヤをドメインモデルの一番上に置いて、サービスレイヤを作るよう推奨していることが、混乱のそもそもの原因です。 ただしこれは、振る舞いのないドメインモデルを作るということではありません。 そうではなくて、サービスレイヤの支持者は、振る舞いをたくさん含んだドメインモデルと一緒に使っています。

Eric Evans は、素晴らしい著書『Domain Driven Design』の中で、これらのレイヤについて次のようなことを言っています。

アプリケーションレイヤ(サービスレイヤのこと):ソフトウェアが何をしなければいけないかを定義し、ドメインオブジェクトに対して、問題を解決するよう命令する。このレイヤの役割はビジネス活動にとって重要であり、別のシステムのアプリケーションレイヤとやり取りをするのにも必要である。このレイヤは薄く保たれている。ビジネスルールやナレッジを含むものではないが、その下のレイヤにあるドメインオブジェクトの協調関係に対して、タスクを調整したり、仕事を委譲したりしている。これはビジネスの状況を反映するものではないが、ユーザーやプログラムの進捗状況を反映することは出来る。

ドメインレイヤ(モデルレイヤ):ビジネス、ビジネスの状況に関わる情報、ビジネスルールについての概念を表す。ビジネスの状況を反映する情報は、ここで管理・使用される。技術的には、その情報はインフラ側でストアされている。このレイヤはビジネスソフトウェアの魂である。

ここでのキーポイントは、サービスレイヤは薄い、という点です(キーとなるロジックはドメインレイヤに置かれています)。彼はこの点についてサービスパターンの中で何度も言及しています。

現在よくある過ちは、適切なオブジェクトに振る舞いを割り当てることを、あまりにも簡単に諦めてしまっていることです。徐々に手続き型プログラミングになっているのです。

なぜこのアンチパターンが一般的になっているのかよく分かりません。 真のドメインモデルをちゃんと使っていないのが原因ではないかと思っています(特にデータ系からきた人たちが)。 それを助長している技術にも原因があります(J2EEのEntity Beanとか。だから私は POJO ドメインモデルが好きなのです)。

サービスの中に振る舞いを見つければ見つけるほど、ドメインモデルのメリットを奪っていくでしょう。サービスの中にすべてのロジックを埋めてしまうと、何も見えなくなってしまいます。