Newuserguide意訳 - More on models
More on models
それではもうすこしmodelについて見ていきましょう。
HelloWorldでの例はWicketで最もシンプルなmodelの実装方法でした。
public class HelloWorld extends WicketExamplePage { public HelloWorld() { add(new Label("message", "Hello World!")); } }
Labelを生成する際にコンストラクタで指定した第1引数はHelloWorld.htmlでLabelがタグと結び付くWicketIdになります:
<html> <head> <title>Wicket Examples - helloworld</title> <link rel="stylesheet" type="text/css" href="style.css"/> </head> <body> <span wicket:id="mainNavigation">main nav will be here</span> <span wicket:id="message">Message goes here</span> </body> </html>
Labelを生成した際の2番目のパラメータがLabelのためのmodelになります。そしてそれはLabelが置かれるタグの中にどんなテキストで置き換えるかという文字列を指定することになります。上の例ではLabelを生成するさいにコンストラクタに指定しているmodelはたんなるString型の文字列に見えます。しかしこれはLabelクラスのコンストラクタの中身を確認してみると、このコンストラクタが便利に使えるような仕組みであるだけなことに気がつきます。それは次のようにコンストラクタ内で文字列をModelオブジェクトに変換しているということです。
public Label(final String id, String label) { this(id, new Model(label)); }
Labelの継承関係を見てみるとLabelクラスがWebComponentを継承していることがわかります。また、そしてWebComponentはComponentクラスを継承しています。これらのSuperクラスはのそれぞれ2つだけコンストラクタを持っています。そのコンストラクタの一つがコンポーネントIDを指定するString型の文字列を引数を持つコンストラクタです。
public Component(final String id) { setId(id); }
そしてもう一つがIDを指定するStringとImodelを引数を指定するものです。
public Component(final String id, final IModel model) { setId(id); setModel(model); }
IModelはすべてのmodelオブジェクトが実装しなければならないインタフェースです。次のコード見てください。
public interface IModel extends IDetachable { public Object getObject(); public void setObject(Object object); }
そしてベースインタフェースIDetachableは次のようになります。
public interface IDetachable extends Serializable { public void detach(); }
これらの詳細はWicketを初めて触るユーザーには特に面白くないと思いますので、詳しくはあとで説明することにします。ここで重要なことはComponentクラスのコンストラクタがComponent(final String id, final IModel model)でいうことです。
modelクラスの中をもう少し見てみると、modelオブジェクトがただのSerializableオブジェクトを持つただのラッパークラスであることがわかります。
private Serializable object;
モデルのオブジェクトはクラスタ環境でWebアプリケーションでの配置をサポートするためにすべてSerializableです。同じく Serializableを継承するするIModel、IDetachableから、すべてのIModelのラッパークラスがすべてSerializableということになります。つまりWicketのmodelはそれ故にserializableであって、クラスタ環境のサーバー間にレプリケーション可能ということを意味しています。ここれですべてを理解できている必要はありません。後述で詳細に説明しますので。
Working with POJOs
上記の例"Hello World"の文字列の出力例を示しましたが、使い勝手があまり良くない場合があります。それではどのようにWicketがドメインオブジェクトでサポートしていくかを説明します。今回はこの例の為に次の普通のオブジェクト(POJO)を使用します。
import java.util.Date; public class Person { private String name; private Date birthday; public Person() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }
Static models
先ほどの例と同等に最も単純な方法はモデルのコンストラクタに文字列を指定して暗黙のうちにmodelオブジェクトを生成する方法です。
add(new Label("name", person.getName()));
また、内部的には同じですが明示的にmodelオブジェクとを生成することもできます。
Model model = new Model(person.getName()); add(new Label("name", model));
これは最初の例と同等にModelオブジェクトに参照をもっていることは何らかわりません。しかしこのようにすることで、他のコンポーネント間でModelオブジェクトを共有することが可能になります。
このようにModelを使うことは、あたえた文字列のないように変更がない場合は、なんら問題ない書き方です。これらのモデルをModelと呼ぶか、あるいはModel自身がたくさんのデータと同期しなければならない場合の、プッシュModelとして利用できます。