Hatena::ブログ(Diary)

出羽ブログ RSSフィード

Seasar Conference 2008 Autumn - 9/6(SAT), Tokyo

2008-06-17

繰り返し項目の実装はDtoとEntityのどちらを使うべきか?

| 17:46 | 繰り返し項目の実装はDtoとEntityのどちらを使うべきか?を含むブックマーク

『複数レコード処理(繰り返し)』の場合に、Entityをそのまま使うというのに違和感を感じてしまうのですが、そんな感覚にはこだわらない方が良いのでしょうか。


導出項目を得るような処理というのはプレゼンテーションロジックなのだから、DTOに値をコピーして、DTOのgetterで実装するようにした方が良いような気がしてしまっているのですが。

2008-06-06 - 出羽ブログ

私の以前のエントリでは、繰り返し更新がなければDtoのではなく、Entityを積極的に使うことを書きました。でもDtoを使うケースでも特に問題ないと思います。ただし、メリット・デメリットは、把握しておいた方がいいと思います。


【メリット】

  • 繰り返し処理には、常にDtoを使うため、設計に一貫性がでる。実装者も迷わない。

【デメリット】

  • プレゼンテーションモデル側で導出項目のロジックを用意すると重複しやすい。
  • 繰り返し更新が必要となるケースは比較的少ない状況において、手軽にEntityで実装できてしまうものをわざわざDtoを作るのが面倒。
  • EntityからDtoへの詰め替えコストも掛かってしまう。

この手の問題は、以前に書いた以下のエントリの問題に帰着すると思います。


 「8割の簡単な処理」と「2割の複雑な処理」への対処方針

 http://d.hatena.ne.jp/dewa/20080531#1212211267


Dtoを使うパターンは以下に相当します。

[方針2] 2割の複雑な処理にあわせる 
品質重視。ただし、簡単な処理の生産性は落ちる。

状況に応じて、EntityとDtoを使い分けるパターンは以下に相当します。

[方針3] 両方の対処方法を用意して、使い分ける 
最適化重視。ただし、厳密な使い分けは難しい。 

そんな訳で、どちらの方針を取るべきかは、プロジェクト単位で

決めてしまえば良いと思います。開発コストと設計の良さとのトレードオフですね。

どちらの方針も悪くないと思います。

大切なのは、一旦方針を決めたらそれを徹底することではないでしょうか。

yukiaraiyukiarai 2008/06/17 19:02 コメントに対するコメントをありがとうございました。腑に落ちたというか、私には、とても納得できる御説明でした。

結局は、手間・実行速度と形式的な美しさのトレードオフに帰着するところであり、ロジックをエンティティとサービスのどちらに書くのかという問題とともに、「両方の対処方法を用意して、使い分ける」のが良いのだということになるのだと思います。

プロジェクトによっては、方針を決めてしまっても良いかと思うのですが、なるべくならば、両方ありにして、どちらの書き方が良いか試行錯誤できるようにしておきたいように思いました。本当は、プレゼンテーションロジックをDTOに実装して、共通化できるのが一番良いのでしょうが、なかなかそういう実装には、一足とびにはたどりつけないでしょうから。

yukiaraiyukiarai 2008/06/17 21:17 S2BeanUtilについてのコメントもありがとうございました。なるほど、と思いました。

私がちょっと頭が固かったのでしょう、出羽さんが例示してくださったような使い方というのが思い浮かんでおりませんでした。ただ、ListからListへの変換を書くときに、毎回、ループをコーディングしなくてすむというメリットにばかり意識がいっていて、結構、面倒なOGNLを記述することも甘受してよいように考えておりました。

後は、EntityとDTOでプロパティの名前だけを変えるような場合を、どのように考えるかとかですね。これも要するに、適宜、使い分けて行くというのが妥当なスタンスなのでしょう。

dewadewa 2008/06/17 21:39 ああ、なるほど。ListからListへの変換についてはあまり考えていなかったことに気づかされました。簡単なケースはEntityのリストを渡していたし、複雑なケースは2WaySQLの戻り値のDtoのリストを渡していたので。

> 後は、EntityとDTOでプロパティの名前だけを変えるような場合を、どのように考えるかとかですね。
昔はS2Dxoを使ってたけど、今の自分だったら、メンバーにS2Dxoを覚えてもらうコストを省きたいので、
Beansで一件分の変換メソッドを作ってもらって、ループ処理してもらうようにお願いするかなぁ。

kuroppekuroppe 2008/06/18 17:57 これは知りませんでした。

S2Dxoで実現できる「プロパティからプロパティのコピー」だけなら
BeanUtilを使えば、Dxoインターフェイスすら不要ですもんね。

これにちなんで質問なのですが・・・
サンプルの
public EmployeeDto createEmployeeDto(Employee emp)

のようなメソッドは、dxoパッケージに配置するのがいいのでしょうか?
こんな感じ↓??
public class EmployeeDxo { }

こうすれば、自動DIされそうですね。

dewadewa 2008/06/18 19:26 > public EmployeeDto createEmployeeDto(Employee emp)
> のようなメソッドは、dxoパッケージに配置するのがいいのでしょうか?

いろいろとやり方があると思いますが、
SAStrutsを使う場合は自分はデータ変換用に特別なクラスを作らないです。
データ変換メソッドはデータを扱うクラスであるアクションフォームに書いています。
(アクションフォームを使わない場合はアクションに書く)

http://d.hatena.ne.jp/dewa/20080605#1212675669
を参考にどうぞ。

kuroppekuroppe 2008/06/19 18:50 なるほど、わかりやすい図ですね!

そこでまた疑問なのですが・・・
SAStrutsのページでは、基本的にActionクラスにActionFormも同梱するのを
推奨しているようですが、dewa様の図だと、DtoとしてActionFormを分離
されていますよね。

これによるメリットはなんなのでしょうか?