- - PR -
ロジック層やデータアクセス層でのWeb依存オブジェクトの扱い
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-09-25 14:50
すでに議論し尽くされている話題かもしれませんが、ご意見を聞かせてください。
MVCを完全に分離する場合、ロジック層やデータアクセス層にプレゼンテーション層特有のオブジェクトは持ち込まないのが原則だと思います。 例えば、StrutsでActionをコントローラーの役割に徹底させる場合、Actionからロジック層、そしてデータアクセス層を呼び出す形になると思います。この際、Web依存のHttpServletRequest、HttpSession、Cookie、そしてStruts依存のActionForm、ActionMappingなどの扱いをどうするか問題になります。ActionFormをデータオブジェクトに詰め替えるのはよく行われると思いますが、RequestやSessionについても、それ用のMapを用意して、Actionにて詰め替えを行う、あるいはRequestやSessionにセットする値を束ねて一つのオブジェクトにして、それを渡すといった感じになるのでしょうか。 ロジック層やデータアクセス層にActionFormやRequestが来ているのは気持ち悪いことかもしれませんが、実際には同じプラットフォームで使われるためライブラリは共通で、ロジック層やデータアクセス層が別のアプリケーションから再利用されることもないとすると、わざわざ分離する必要があるのか疑問です。Mockを使えば、RequestやSessionもアプリケーションサーバを起動する必要なく単体テストが実行できるので、わざわざ類似したものを作って構造上は大して変わらないのに見かけ上分離することにどれだけ意味があるのか疑問です。 諸先輩方はどのようになさっていますか。 | ||||||||
|
投稿日時: 2005-09-25 17:02
こんにちは。
ActionMapping: そもそも遷移先の制御に使用するのですからロジック層に与える必要はないでしょう。 ActionForm: データオブジェクトへの詰め替えを行います。BeanUtils.copyProperties()を使用すれ ば、楽チンですね。 HttpServletRequest: requestパラメータはActionFormにてラップされて渡されますので、通常ロジック層 で使用する必要はないでしょう。使用する必要がある場合は、メソッド呼び出しで 取得した結果をロジック層に渡します。 HttpSession: Sessionに登録したObjectを取り出して、ロジック層に渡します。 Cookie: 使用用途はユーザID等のデフォルト表示用、SessionIdの格納ぐらいでしょう。 SessionIdは通常ロジックで触ることはありませんし、デフォルト表示用のユーザID等 は、Action内でセットしてしまえばよいかと思います。 という形で、明確な分離が行えると思っていますがどうでしょうか? ん、HttpSessionBindingListener等を使いたいときは、どうすればいいんだろう?
んー、これは悩みどころですが、「再利用されることがない」という前提が本当に正しいかどうかがポイントとなるような気がします。あ、でも仮に本当に再利用されることがなかったとしても、コントローラとロジック層は分離されるべきなので、どうせ分離するのだったら正しい形で線を引きましょう。という結論になるのかな? 私もまだまだ悩んでいる部分もあるので、ご参考までに | ||||||||
|
投稿日時: 2005-09-26 08:11
作成したロジックはWebアプリケーション以外で使われることはまずないでしょうからロジックをサーブレットから分離するのはムダです。
逆に再利用の前提があるのであればそうした分離を行われるのがよいでしょう。 ちなみに私は分離はしません。複雑性を増してまで分離をしてWeb以外でロジックを再利用した経験がないからです。 | ||||||||
|
投稿日時: 2005-09-26 23:24
確かに、ロジックを再利用することって、経験上ないですね。
ただ、そのプログラムが使いすてなのか、何十年と保守して いくか、規模がちっちゃいのか、10数人のプログラマに依頼 するほど規模が大きいのかといったことも判断材料にあなるか と思いました。 規模が大きくなり、関係するプログラマが多くなると、Action だけで作らせると、1冊の物語のようなメソッドのソースができあがり 変更要求が発生したときに、誰がなおすんだろうか?と青ざめること も多々あります。そういったときに、骨組みとして、Actionは こうで、ロジックはこうで、DBアクセスはこうね。というきめ ごとをつくれば、そこそこの物があがってきて、あ、これならここ を直せば、影響範囲はここねみたいに、保守しやすくなるのかなと 思ったりします。 しかし、そこまで複雑なロジックになるなら、WEBじゃないだろ という意見もありますが。。。 | ||||||||
|
投稿日時: 2005-09-26 23:42
比較的小規模で、開発者全員がちゃんと認識していれば良いと思うのですが...
良く見たのは、HttpSessionなんかのように何でも値を格納できる便利オブジェクトを あちこちにたらい回しにすると、何でもかんでもそれに入れてしまって、 アプリケーションが1枚岩になってしまっているのがあります。 そうすると、UIをちょっと変えるだけで、プレゼンテーション層からビジネスロジック層、 永続化層まで全部見ていかないといけなくなったり。 ある程度の規模になったら、再利用性うんぬんよりも、「見て、考えなければならないスコープ を限定する」と言う意味で、レイヤ(とそこで使うでデータ)を明確に分離するのは 価値があると思います。 | ||||||||
|
投稿日時: 2005-10-02 22:34
皆さんご意見ありがとうございます。
少し間が空いてしまいましたが、この間いろいろ悩んでいて、どうすべきか という結論や自分の意見がまとまらず、書くのをためらっていました。 まだ、まとまっていませんが、いろいろと試してみました。 sessionオブジェクトをロジック層には渡さないように修正することは何とか できました。確かにこの方が整理されてすっきりします。 ActionFormについては、全層に渡ってしまい、これをDTOに変えることは、 変数名の修正も含むので、これは厄介な作業になる上、単にロジックや データアクセス層にActionFormがあるのが気持ち悪い、という以外に別段 問題はありません。 ActionFormを入力に限定し、出力には別のデータオブジェクトを使うというのも 重複が多いため、無駄な感じがしています。この部分は最初からきっちりさせて おくべきでしたが。 | ||||||||
|
投稿日時: 2005-10-02 23:21
こんばんは。
開発が始まってしまったコードに対しては無理に修正をかける必要はないのではないでしょうか。 修正コストと実益を天秤にかけた場合、割りに合いそうもないですし ポイントは今後の開発にどう繋げて行くかでしょう。 ActionForm と DTO の重複を無駄と思うかどうかについてですが、私は無駄であ るとは思いません。 ActionForm を使用するということは、そのロジックが Struts に依存しているこ とを意味します。Struts より遥かに高機能なフレームワークが今後出現した場合、 Web以外の環境でロジックを使用したい場合等に、Struts に依存しない既存ロジッ クは手を加えずに再利用出来るが、依存するロジックは手を加える必要があると いう点で違いが発生してきます。 私の経験上では、その分離はコストがかかる作業ではありませんし、コードの複雑 性が増す要因となることもありませんでした。 ただし、再利用が行われたケースも今のところないのですが | ||||||||
|
投稿日時: 2005-10-02 23:40
>Anthyhimeさん
確かに業務ロジックを再利用する事は殆どないですね。 私の場合、再利用性が高い場合は業務ロジックの引数に インターフェイスを使用します。 インターフェイスの実装が、 ・リクエストをラップ ・アプレットからの入力をラップ ・WEBサービス等の入力をラップ という感じに、必要に応じて作成する感じになります。 (これがDTOなのかな・・・用語がよくわからないもので・・・) とはいえ、わざわざインターフェイスを使用したところで、 再利用された経験がなく、 ごりごりと作った方が早い場合が多いですね。 特に最近は小規模な開発も多いですし、 理想的な構成よりも、小回りが利く作り方が必要だと感じます。 |