特定のユースケースに関連する複数のクラスを1つのパッケージに集める

特定のユースケースへの要件が少ない場合は、
ユースケースに対応した1つのActionクラスで基本的な処理は実装できます。


しかし、ユースケースへの要件が多い場合は、扱うクラスが増えてしまいます。
例えば、ユースケース専用のDto(ActionForm)やユースケース専用のLogic、セッション格納用Dtoなどです。


特定のユースケースに関するクラスが複数存在する場合は、
パッケージが分散しているよりも、1つのパッケージに集めた方が開発しやすいと思います。
(Teedaはこのような構成でした。)


そこで、ユースケース名が "hoge" の場合、以下のような構成が可能なように
SAStrutsを拡張してみました。


Java側:
<ルートパッケージ>.web.hoge.HogeAction.java
<ルートパッケージ>.web.hoge.HogeDto.java (ActionForm)
<ルートパッケージ>.web.hoge.HogeSessionDto.java
<ルートパッケージ>.web.hoge.HogeLogic.java

JSP側:
webapp/hoge/add.jsp
webapp/hoge/xxx.jsp
webapp/hoge/yyy.jsp



イメージとしては、こんな感じです。ネストしたユースケースも扱うことができます。


実際に作成してみたアクションクラスは次のようになります。

package tutorial.web.hoge;

import org.seasar.framework.container.annotation.tiger.Binding;
import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;

public class HogeAction {

    @ActionForm
    @Binding(value="hoge_hogeDto")
    public HogeDto dto;

    @Binding(value="hoge_hogeLogic")
    public HogeLogic logic;

    @Execute(validator = false)
    public String add() {
        return "add.jsp";
    }

    @Execute(input = "add")
    public String doAdd() {
        dto.result = logic.add(dto.cast());
        return add();
    }
}

actionパッケージではなく、webパッケージ(S2標準のサブアプリケーションルート)の
直下にhogeというユースケースのパッケージを作成して、
そこにアクションやDto、ロジックといったクラスを配置しています。


同一パッケージなので、HogeDto やHogeLogic のインポート文も存在しません。


@Bindingアノテーションが微妙にうっとおしくなったので、
HogeDtoの代わりにDto、HogeLogic の代わりにLogicというクラス名にする
大胆な案も試してみました。
プロジェクトにDtoやLogicという名前のクラスが多数できて、
気味が悪いけど、別パッケージなので、一応できてしまいます。
ちなみに、こんな感じ。

package tutorial.web.fuga;

import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;

public class FugaAction {

    @ActionForm
    public Dto dto;

    public Logic logic;

    @Execute(validator = false)
    public String add() {
        return "add.jsp";
    }

    @Execute(input = "add")
    public String doAdd() {
        dto.result = logic.add(dto.cast());
        return add();
    }
}

さっきのHogeActionを比較するとずいぶんとスッキリとした印象を受けます。
確かに、ソースコードは読みやすいけど、
Eclipseで検索した時に同じ名前のクラスがたくさん出てくるのはちょっとイヤだし、
あまり前例がなく大胆すぎるので、心残り(*)だが自分としてはボツと考えることにしました。
(* 「書き易さ < 読み易さ」という意見を考慮すると…。)
(@Bindingアノテーション無しで public HogeDto dto; と記述できるとベストなんだけどなぁ。)


実際のSAStrutsの拡張方法をブログに書こうかと思ったけど、
次の5つのクラスをそれぞれ継承したクラスを作成して、
web.xmlとcustomizer.dicon の修正が必要なので説明が結構大変そうだ。

  • RoutingFilter
  • S2ActionMapping
  • S2ModuleConfig
  • S2ModuleConfigFactory
  • ActionCustomizer


頑張ってSAStruts拡張の説明をするよりも、
この仕組み自体をSAStruts本体に組み込まれてもよさそうな気がしてきた。