Action と Form オブジェクトの分離

現在の S2JFace は、S2JSF(またはTeeda)の提供する ValueBinding と似たような機能を提供しています。

具体的には、画面上のテキストフィールドなどに入力された値を POJO である Action クラスのフィールドに自動的にセットしたり(ImportValue)、逆に画面表示時に Action クラスのフィールドを画面へ自動的にセットしたり(ExportValue)できます。

今までは、ValueBinding の対象を Action クラスとしていましたが、この場合、ボタンなどが押された時に呼び出されるメソッドも Action クラス上にあり、データとコントロールが分離されていないことになります。

また、編集画面と参照画面など、同じデータセットを扱う複数の画面が存在する場合、画面と Action クラスが1対1対応であるため、ValueBinding を利用するためには複数の Action に同じようなフィールドを持たせなくてはなりません。(これを回避するには、フィールド部分のみをスーパークラスに共通化すれば良いのですか、ちょっと汚い感じがします)

そこで、データを持たせるオブジェクトを新たに「Formクラス」として Action から分離させようかと考えています。メソッドバインディングの呼び出し先はあくまでも Action クラスですが、ValueBinding の対象となるのは Form クラスになります。Form クラスの参照は Action クラスに対してインジェクションされので、Action クラスからは Form クラスの持つデータを従来通り使えます。

Form クラスは POJO であり、単なる JavaBeans です。というか、S2JSF における DTO と同じ位置づけです。ただし、Form クラスは画面と1対1または多対1の関係になります。多対1というのは、先ほど提示したように同じデータを扱う複数の画面が存在する場合、それぞれの画面から参照できるようにするためです。

画面とFormクラスの対応は、基本的に命名規約によって決まり、「画面名 + Form」が Form クラスのコンポーネント名になります(Form クラスは S2Containerに登録する必要があります)。

たとえば、「Employee」 という名前の画面があった場合、「EmployeeAction」が Action クラス、「EmployeeForm」がForm クラスのコンポーネント名というわけです。

画面と Form が多対1の関係になる場合、Form と画面の関係は Action クラスにアノテーションで記述します。たとえば、EmployeeEdit と EmployeeView という画面が存在し、それぞれ EmployeeForm を利用する場合、EmployeeEditAction と EmployeeViewAction というそれぞれの Action クラス(画面とActionは必ず1対1になります)に、以下のようにアノテーションを記述します。

@Form(EmployeeForm.class)

このようにして画面をコントロールすべき Action クラスと、プレゼンテーションモデルとなる Form クラスを明示的に分離することで、画面が作りやすくなるはずです。これで、S2Dao によってデータベースから取得したドメインモデルをロジック上でS2Dxoを使ってプレゼンテーションモデルであるFormオブジェクトに変換、それをS2JFaceが画面へ自動バインディングするという流れになります。

結局、「Teeda の Page クラスと何が違うの?」と聞かれるとつらいのですが、Teeda の Page クラスはこのあたりを明示的に分けていないような気がするのですが、どうなんでしょう?