-SWT/JFace in Action

最近のManningは侮れませんね。「SWT/JFace in Action」。出たら即買います。内容についての記述を読むと、Draw2DとGEFにも言及しているらしいです。おそらく続く同類の書籍はでないでしょう。一時期のオライリーもとんでもなかったですが、ことJavaオープンソースという潮流の中で最近はManningのシリーズの押さえ方はハンパじゃないと思います。「Hibernate in Action」は最近また「MEAP」というアーリーアクセスプログラムが始まりましたが、共著者の一人がGavin Kingです。「Tapestry in Action」のHLSといい、どういう押さえ方してるのかと思います。普通には、HibernateTapestryも書籍これ以外にでないでしょう。出るとしたら一冊だけ日本語版です。おそらく世界で日本人だけが英語の書籍読まないので。
MannigのMEAPの仕組みをまねっこしたい出版社の方がいたら、つくりますよ〜。Tapestry+Seasar2で(笑。作るのにおそらくたいした工数かかりません。

-JUnitの本

JUnit Recipes」期待の一冊です。JUnitオライリーでもこれから出るみたいです。読めばがっかりかもしれないけど。
というのも、「JUnitによるテストファースト開発入門」を読了しましたが、私は内容の乏しい残念な本だとがっかりしたのです。もうね、これだけWEBで情報とれるんだから、「総論的な入門書」はいらんのです。あまつさえJUnitの本なのに、TestCaseについてはJUnitのサイトドキュメント読めって、なんじゃらほいです。いいわけ的に前書きで「そういう技術特化の本じゃない」っていうけど、Mavenのインストール本がその回答じゃないと思いました。まあ、自分を棚に上げるからいえる所業ですけど。。。
ほんとに書いてほしかったのは、JUnitを導入することによって、テストのしやすい設計やコードというのの存在が見えてくるところにあったと思います。ユニットテスト導入以前と以後で設計やコードがささいなことでもどう変ったかを自覚しない方はいないと思うのです。「ユニット」テストのユニットたる所以をどうとらえるか。ユニットの単位感覚であったり、隠蔽のさじ加減だったり。人によってはそのユニットが(ステップ数としても)とても大きかったり、小さかったりするわけです。オブジェクト指向的にできる限り隠蔽したときに、privateなメソッドって外部から叩けないから、ユニットテストできないのですよ。だからって単純にpublicにしますか、と。

-Tapestryサービス(2)

サービスに対するURLもサービスで生成管理します。PageServiceは、IEngineService#getLink()を以下のように実装してします。

public ILink getLink(
    IRequestCycle cycle, IComponent component, Object parameters) {
  if (Tapestry.size(parameters) != 1)
    throw new IllegalArgumentException(
      Tapestry.format("service-single-parameter", Tapestry.PAGE_SERVICE));
  return constructLink(
    cycle, Tapestry.PAGE_SERVICE, new String {(String) parameters[0]}, null, true);
}

このgetLink()メソッドが返す、ILinkは、getURL()メソッドでString型のまさにURL表記文字列を返します。PageService#getLink()中で用いられている、constructLink()は、基底のAbstractServiceクラスにて定義されていて、ILinkの実装を返す機能を持っています。このメソッドの引数は、constructLink(IRequestCycle, String, String, Object, boolean)となっていて、第二引数にサービス名(ここでは「page」)、第三引数にサービスコンテキストを指定すると、望むURLが生成される仕組みです。
この、PageService#getLink()は、PageLinkコンポーネントから呼び出されます。すなわち、HTMLテンプレートに、以下のようなコードで定義します。

<a href="#" jwcid="@PageLink" page="SomePageName">click me</a>

この時、PageLinkコンポーネントレンダリング時に、org.apache.tapestry.link.PageLinkクラスからめぐりめぐってorg.apache.tapestry.link.AbstractLinkComponent#getLink()を呼び出されます。このメソッドの内容は以下のとおりです。

protected ILink getLink(
    IRequestCycle cycle, String serviceName, Object[] serviceParameters) {
  IEngineService service = cycle.getEngine().getService(serviceName);
  return service.getLink(cycle, this, serviceParameters);
}

必要なサービスをエンジンから取得して後に、サービスに実装されているgetLink()を呼んでILinkオブジェクトを生成しています。DirectService-DirectLink、ExternalService-ExternalLink、ActionService-ActionLinkもサービスの内容こそ異なりますが、リンクメカニズムは同様です。
Formはすこし複雑で、状況に応じてDirectServiceかActionServiceどちらかと連携しますが、やはりサービスの生成するURLを用いています。(つづく)