C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2007/10/19 22:12

Martin Fowler's Bliki in Japanese - ドメインモデル貧血症

有名なアンチパターンです。僕も昔やってしまったことがあります。

例えば、図書の貸出システムを作るとします。このシステムは利用者が直接操作し、借り入れ手続きや返却手続きを行います。

ドメインモデルを適切に適用した設計では、「書籍」クラスや「利用者」クラスを用意し、「利用者」クラスに「借りる」メソッドや「返すメソッド」を用意するでしょう。

public sealed class 書籍
{
    public int 管理番号 { get { ... } }
    public string タイトル { get { ... } }
    public string 著者 { get { ... } }
}

public sealed class 利用者
{
    public int 利用者ID { get { ... } }
    public ReadOnlyCollection<書籍> 借りてる書籍 { get { ... } }
    public void 借りる(書籍 対象書籍) { ... }
    public void 返す(書籍 対象書籍) { ... }
}


しかし、ドメインモデル貧血症に陥っている設計では、「利用者」クラスに「借りる」メソッドや「返す」メソッドがありません。代わりに、「借り入れ操作」クラスといった感じの、ロジックのみのクラスが存在します。

public sealed class 利用者
{
    public int 利用者ID { get { ... } }
    public ReadOnlyCollection<書籍> 借りてる書籍 { get { ... } }
}

public sealed class  借り入れ操作
{
    public void 借りる(利用者 対象者, 書籍 対象書籍) { ... }
    public void 返す(利用者 対象者, 書籍 対象書籍) { ... }
}


ドメインモデル貧血症では、データと処理が分離されてしまいます。これは決してオブジェクト指向ではありません。
また、この例では、「利用者」が「借りてる書籍」を、読み取り専用コレクションのプロパティとして公開しています。「借り入れ操作」クラスは、「借りてる書籍」をどうやって変更するのでしょうか。カプセル化を崩すか、プロパティの型を読み取り専用でなくするか、あるいは利用者クラスに補助的なメソッドを用意するか。どうするにしろ、複雑さが増してしまうかと思います。


オブジェクト指向じゃないことが悪いのではありません。オブジェクト指向を適用しているつもりで貧血症を起こしているからダメなのです。











トラックバックURL↓
http://csharper.blog57.fc2.com/tb.php/170-6e07cef3