SE(たぶん)の雑感記

一応SEやっている筆者の思ったことを書き連ねます。会計学もやってたので、両方を生かした記事を書きたいと考えています。 でもテーマが定まってない感がすごい。

「ドメインモデル貧血症」を見かけたので、誤解しないように備忘録

ドメインモデル貧血症、という言葉があります。

説明を引用すると、

大半がpublicなゲッターセッターで、単に属性と値を保持するだけのオブジェクト

を、「ドメインモデル」と呼んでいる症状、とのことです。*1

そんなソースをつい最近見かけ、また、紛らわしい場合もあるので、それについて書いてみます。

忘れてはいけないこと

publicなゲッターセッターのみのクラスが、全て貧血症、というわけではない。
意図してそうしているなら、それは問題ない。

見つけたソース(イメージ)

Javaです。

  • 貧血症クラス定義
public class TeamInfo {

    private String teamCode;
    private String teamName;
    private ArrayList<User> teamMember;

    public String getTeamCode(){/*省略*/};
    public void setTeamCode(String code){/*省略*/};
    public String getTeamName(){/*省略*/};
    public void setTeamName(String name){/*省略*/};
    public void add(User user){/*省略*/};
    public List<User> getMember(){/*省略*/};
}
  • 利用者
// O/Rマッパーへのアクセスと仮定
Team team = Teams.findByName(name);

TeamInfo info = new TeamInfo();
info.setTeamCode(team.getTeamCode);
info.setTeamName(team.getTeamName);

List<TeamMember> member = Teams.findMember(info.getTeamCode());
for (TeamMember m : member) {
    info.add(Users.findById(m.Id));
}

int total = 0;

for (User user : team.getMember()) {
    total += user.getPoint();
}

/* 以下省略 */

貧血症たる所以

こういう特徴があるため、ドメインモデル貧血症を発症している、と見受けられます。

  • TeamInfoクラスは、データを受け取って利用される、ゲッターとセッターしか持っていない
  • TeamInfoクラスに格納された情報を使って、別の処理を行っている

特に、二つ目の理由が重要です。

DDD上、ゲッターで情報を取り出し、セッターで値を書き込むだけなら、そのクラスに処理を動かすという対応が鉄則です。

ゲッターセッターだけのクラスが許される場面

こういう場合は、ゲッターセッターだけのクラスの存在が許容されると考えられます。

  • リクエスト、レスポンスの変換用クラス
    それらでフォームやJSONを使う場合です。
    特に、GsonJson.NETを使う場合、変換クラスはフィールドと、プロパティのみにになります。

  • O/Rマッパーが生成したクラス
    O/Rマッパーは、コードファーストならともかく、自動生成なら、余計なものは入れず薄く保ちましょう。
    いくら、C#だとpartialクラスを作れるからといって、そこにロジックを詰め込むのは止めましょう。*2

  • テスト用
    当然です。

言いたいこと

大半がpublicなゲッターセッターで、単に属性と値を保持するだけのオブジェクト

が、全て悪ではない、ということです。

DDDについて知らない人*3に、ゲッターセッターだけのクラスは良くない!という言葉だけを伝えると、混乱すると思うので、書いた次第です。
…私も、どうだったっけ?と思いながら、改めて書籍を探った次第です。

元ネタを探る

『実践ドメイン駆動設計』(IDDD)で出てくる言葉です。

honto.jp

あと、こちらにも。

honto.jp

本当の元ネタは、Martin Fowlerが書いた、

martinfowler.com

らしいです。*4

おわりに

DDD(ドメイン駆動設計)ネタは、書きたいと思いつつも、なかなかとっかかりがない状態でした。
徐々に、思うこと等を書いていけたら、と思っています。


*1:『実践ドメイン駆動設計』 1.2 あなたがDDDをすべき理由 貧血と記憶喪失

*2:動的に列を作成する用途には使えた

*3:どのクラスがドメインモデルであるか判別できない人

*4:IDDDで引用されている