複数種類のエンティティを扱うロジックをどこに書くのか

「複数種類のエンティティを扱うロジックをどこに書くのか」、これは、非常に難しい問題です。エンティティに持たせると、どこのエンティティに持たせるのかを判断するのが難しい。

だから、アクションにもたせるのが良いと書いてきました。

でも、売上金額 = 売上明細.商品.単価 * 売上明細.数量みたいなロジックがあって、JSPに売上金額を表示する場合に、このロジックをアクションにもたせるかというと微妙ですね。

2008-02-08 - yvsu pron. yas

全てのケースに当てはまるとは限りませんが、このケースでの解は、売上金額をプロパティと見なして、エンティティのクラス設計を見直す、ではないでしょうか?

私なら、売上金額の値には売上明細と1対1という関連があるので、売上金額プロパティを非永続化プロパティとして売上明細に追加します。例えば、以下のような感じで。

public class 売上明細 {
  // 色々省略
  public int get売上金額() {
    return 商品.単価 * 数量;
  }
}

結局は、ひがやすおさんの売上明細にロジックを持たせるという結論と同じかもしれませんが、「そのメソッドでアクセスするプロパティをもっとも多く所有しているエンティティ」は何か?ということで悩む必要はありません。データ構造の観点から見て、売上金額プロパティはどのエンティティが所有すべきかで判断しました。場合によっては、売上プロパティを持つ新しいエンティティを作った方が良い事もあるかもしれません。

要するに「複数種類のエンティティを扱うロジックをどこに書くのか」に悩む場合、そのロジックがあるべきクラスがないのが問題で、そのロジックに関係するクラスの設計を見直す必要があるのではないか、ということです。メソッドを追加することを考えるだけでなく、新しいクラスを追加する、クラスに新しいプロパティを追加する、とか。

と、ひがやすおさんのエントリを見て、なんか納得感が得られなくて色々考えてみたら、こんな結論に行き着きました。


今回のケースだと、「複数種類のエンティティを扱うロジックをどこに書くのか」という問題設定にしたのが、問題をややこしくしたのかもしれません。

「ロジック」と見なしちゃうと、このメソッドはどこに追加するのが良いのか?という問題になってしまい、よく分からないから、適当なutilクラスのstaticメソッドにしてしまえ、などと考えてしまいがち。というか、私もそういう間違いをよくやったような気が・・・(苦笑)

「売上金額 = 売上明細.商品.単価 * 売上明細.数量」のロジックの結果に着目していれば、売上金額はデータなので、「複数種類のエンティティから導出されるデータはどのクラスが所有すべきか」という問題になります。これなら、上で書いたように解が割とすっきりする。

まぁ、その問題設定の誤りに気がつくのが難しいですね。私も結論に行き着いてから気がつきました。