JSP と ViewHelper
DBから取得した内容等をJSPに表示する場合、一般的にはJSP上でEL等を使用して、プロパティ名によるアクセスを行なうと思います。このような場合にサービス層から取得されたモデルなどのJavaBeansを直接リクエストやセッションの属性に設定して利用するのではなく、ViewHelper を利用すると作りやすかったりします。
JSP上での表示項目は JSP の都合によった名前をつけ、対応するプロパティを各画面専用の ViewHelper クラスに定義します。ViewHelper ではモデルなどの JavaBeans を受け取り、プロパティのゲッターメソッドでそれぞれのモデルのプロパティ値を返したりします。
ボタンの表示制御に使用するフラグ値も ViewHelper が返すことによって、 JSP 上に記述する
以下に ViewHelper を利用する JSP の例*1を記述します。
<html> <body> <form ...> 名前: <c:out value="${helper.name}"/> <c:if test="${helper.visibleSaveButton}"> <input type="submit" value="保存"/> </c:if> </form> </body> </html>
JSP では、サービスからどのような形で情報が取得できるかは気にせずに、JSPが欲しい情報を EL を利用して記述して行きます。
helper.name は名前として表示したい値を表していますし、helper.visibleSaveButton はその名前のとおり、保存ボタンの表示有無を表しています。
ViewHelper ではこれらのプロパティ値のゲッターメソッドを定義します。これらのプロパティ値の情報元となるのはサービス層から取得したモデルだったり、Strutsでいうところのアクションクラス内で作成した情報だったりします。
作成した ViewHelper はリクエストやセッションの属性に "helper" という名称で設定しておきます。そうすることで helper.name や helper.visibleSaveButton のような名前によってJSPからアクセスされます。
ViewHelper の例*2を以下に記述します。
public class SampleViewHelper { private SampleModel model; private LoginUser loginUser; public SampleViewHelper( SampleModel model, LoginUser loginUser ) { this.model = model; this.loginUser = loginUser; } public String getName() { return model.getName(); } public boolean isVisibleSaveButton() { return model.getUserId().equals( loginUser.getId() ); } }
このようにして、JSP上からはサービスのモデルを見せないようにしたりします。
こうしてみると、ViewHelper というのは JSP と一組になって View の役割を果たすものという見方ができると思います。Action 等からは ViewHelper が View であり、実際のデザインなどは JSP が担うというような。
JSP だけでViewのすべてをやらせるのはいささか大変なので、ViewHelper はなかなか良い働きをすると思います。
さて、JSP と ViewHelper は対になっており、片方に変更がはいるともう一方に影響を及ぼします。たとえば、JSP 上の helper.name の記述を helper.modelName に変更したとしたら、ViewHelper の方も getName メソッドを getModelName メソッドに変更する必要があります。
このような変更に関する漏れは実際にJSPを動かすまでわからないため、気づきづらいバグが入る可能性があります。
そこで考えたのですが、デザイン用の View 部分(JSP等)から ViewHelper を自動的に生成する仕組みがあれば良いのではないでしょうか?デザイン側に埋め込んだ特定のキーワード、JSPでEL使用の場合は ${〜} 内で使用されているプロパティ名から画面用の ViewHelper クラスのソースを自動生成するような仕組みがあり、デザイン側が変更されるたびに自動的に再生成するとしたら、名称の変更による修正漏れは出ないのではないかと。
このままでは再生成時にプログラマが記述したコードが破棄されてしまうので、実際は ViewHelper のクラスではなくインタフェースを生成し、プログラマはそのインタフェースを実装したクラスを作成するなどすれば良いのではないかと。
JSP にこだわらずに他の View 用のテンプレートエンジンと組み合わせて使用できれば更に便利かも知れません。そうすれば Web 開発にかぎらず、様々な場面(帳票など)でも同じような利用ができるかも知れませんし。
と愚考してみる、テスト。
追伸:
JSF とかならそもそも必要ないかもしれません。JSFはふつうのGUIコンポーネントに値を設定するかのように表示項目の設定が可能だとおもったので。
jsfTextComponent.setText("ほげほげ");// JSFの場合、こんな感じなコードで設定可能