読者です 読者をやめる 読者になる 読者になる

yohjizzz's Blog

I'm a Programmer.

Action と ActionForm

SAStruts を実案件に導入しようとして思ったこと。「ActionForm」編…

≪気に入ってる点≫

  • Action と ActionForm を切り離せる

 入出力項目をフィールド毎にコントローラに定義するのは多くの開発者の方々は戸惑うようですね。
 個々の主観だと思いますが、、、
 昔(Struts⇒Spring MVC)からパラメータはバインド専用のハコに詰める、という感覚が落ち着くんでしょうか。
 Teeda を導入した時も同じような意見を聞きました。実際に項目が多いと可読性は落ちますね。
 個人的には WebWork を使って時期があったのであんまり抵抗ありませんでしたけど。

  • Dto から Form へ

 そもそもPOST送信されるデータ集合であって、基本プロパティを String で保持するので、
 パッケージ構成や命名規則含め、DTO と分割されるのはすっきりします。

≪気に入ってない点≫

 これは実際に試してないのですが、ソースコードを見る限り、、
 ActionCustomizer#setupActionForm() で Action のフィールドを検査して、、
 最初に見つけた @ActionForm のクラスを S2ActionMapping に渡しているので恐らくそうでしょう。
 Action がユースケース単位の場合、ユースケース内で扱うフォームは1つだとは限らないし、
 仮に Action を画面単位に定義したとしても、
 1画面にて複数のフォームが存在するような画面があることもあるでしょう。
 その場合、ユースケース(または複雑な画面)にある複数のフォームの項目を
 1つの ActionForm に定義しなければならないのはちょっと嫌ですね。(主観ですけど…)


 せっかく1つの Action で(わかりやすいURLで)実行メソッドをスイッチできるのだから、
 @Execute を使って実行メソッド単位で ActionForm も指定できれば良いのになぁと思います。
 S2ActionMapping で静的にもつのではなく、
 実行メソッドのように S2ExecuteConfig 辺りでメソッド単位で保持される情報であれば良いなぁ。

  • パラメータのバインド対象の判断が「@ActionForm」の有無である、ということ

 これは ActionForm そのものとはズレますが、
 現仕様では Action のフィールドに1つ以上 @ActionForm が定義されていると、
 バインド対象のオブジェクトを ActionForm に決定する、という点です。


 たとえば、ある Action には @ActionForm は定義されていません。
 でも画面に表示する情報が多数あるので別途 Action に publicフィールドで Dto を定義しています。
 (表示時はこれで問題ありませんね。ELで通常のプロパティとして扱えます。)
 この場合 Action にアクセスする際、hoge/?hogeDto=123 としてしまえば、
 パラメータ「hogeDto」を Action の中に探して "123" をバインドしようとしちゃいますね…


 これを防ぐには、、
 1)表示項目は public にはせず、public な getXxx() を用意する
 2)ダミーの @ActionForm を定義する
 のどちらかになると思います。(すいません。他にうまいやり方があれば御指摘下さい)
 どちらもかっこよくはないなぁ〜
 もともと「publicフィールドなんていらねーんだよ!使うな!」って方式なのであれば1)で良いかもしれませんが、
 せっかく publicフィールドを使っていこうとしてるのにこれじゃなんか悲しい><
 しかも1)を採用するなら customizer.dicon を修正して、
 getXxx() に対してはトランザクションの適用(TxAttributeCustomizer)を外しておきたいですね。


 そもそも @ActionForm がある(ActionForm を利用する)という定義と、
 Action のフィールドに勝手にHTTPパラメータをバインドすんな!という定義は別なのではないでしょうか。
 お互いに排他関係にあるものではないような気がします。
 ・ActionForm にパラメータをバインドする⇒だから Action にはバインドしない!
 というのはokだと思いますが、
 ・Action のフィールドにHTTPパラメータをバインドしたくない⇒なら @ActionForm だね
 といのは違うような・・・

追記

>  この場合 Action にアクセスする際、hoge/?hogeDto=123 としてしまえば、
>  パラメータ「hogeDto」を Action の中に探して "123" をバインドしようとしちゃいますね…

この場合は public フィールドに @Binding(bindingType = BindingType.NONE) で良いのかな?
ちょっと確認してみます。