設定を書きたいのか、書きたくないのか。

ひがさんによる「Seasar2.3にこめたメッセージ」に対する id:da-yoshi さんの反応に反応してみるテスト.

ただ、全てを規約でコントロールしようとすると、逆に開発が規約に縛られるような状況に陥ってしまうのではないかという懸念もあるので、ある程度の範囲にとどめておくべきだとも思います。例えば、トランザクションアスペクト情報を命名規則によって定義するやり方は好きではありません。

ふむ.
好みはね,人それぞれですよね.
でもでも,自分的には

って感じかなぁ.
例に出されているトランザクションについても,アノテーションで指定できてもいいとは思いますが (S2.3 でも EJB3@TransactionAttribute をサポートするかも?),明示的な指定をしなくて済むならそれに越したことはないかな.


多くの場合,トランザクション境界はそんなにきめ細かく設定するものではないと思うんですよね.
例えば CORBA OTS には Transactional Object という概念があります.というか,初期の CORBA OTS にはそのためのマーカインタフェースまでありました (現在は @Deprecated みたいな扱い).
Transactional Object はトランザクション境界の中に生息するオブジェクトで,そのメソッドは全てトランザクショナルな操作ということになります.
そのため,少なくとも CORBA IDL レベルではメソッド単位にこれはトランザクショナル,これは非トランザクショナル,といった指定は出来なかったということになります (暗黙的なトランザクション伝播の場合).
これで不便はなかったかというと,CORBA OTS を実案件で使ったことがないのでよく分からないのですが,おそらく問題ないのではないかと.
なぜなら,一つのクラスがトランザクション境界の中で実行されるべきメソッドと,トランザクション境界で実行してはならないメソッドを併せ持つのは設計がまずい (完全にコンテキストが異なる責務を持たせている) と考えられるから.
効率の問題を考えると,トランザクション境界の中からしか呼び出されないことが分かっているメソッドでトランザクションコンテキストを渡したりチェックしたりするのは避けたいかもしれませんが,CORBA IDL で記述されるのは public つまり外部から呼び出されるインタフェースであって実装クラス固有のメソッドは対象外なので概ね問題なし.
ともあれ (JW),オブジェクト指向トランザクションの経験豊富な連中が作成した仕様である CORBA OTS では,トランザクション境界は非トランザクショナルなオブジェクトとトランザクショナルなオブジェクトの間にあり,トランザクショナルなクラスのメソッドは全てトランザクション境界内で実行されるというシンプルなモデルが考案されていたのです.


このモデルは多くの Web (J2EE) アプリケーションでも有効で,やはりトランザクショナルオブジェクト (トランザクション境界内で使われるクラス) というのはある程度自明なわけです.
いわゆるサービス層とかロジック層とか呼ばれるようなレイヤにあって,プレゼンテーション層などの上位層から呼び出される時にトランザクション境界が設定されるのがよくあるケースではないかと.
こういう,よくあるケースでわざわざ明示的な指定をするのは労力の無駄,あるいはわざわざ墓穴を掘っておくようなものという気のせいがします.


そんなわけで (どんなわけで?),サービス層の境界にある (上位層から呼び出される) クラスは 〜Service ってインタフェースを実装して 〜ServiceImpl って名前を付ける,などの規約で多くの場合は十分だと思う次第.
そして S2.3 の AspectAutoRegisterrequiredTx (EJBREQUIRED 相当) を適用することにすれば,〜Service (を含む) インタフェースで定義されたメソッドに対してのみ,トランザクション境界を設定するアスペクトが適用されます.実装クラス固有のメソッドにはアスペクトは適用されないので効率上も問題ないでしょう.
それに比べて,トランザクショナルなクラス (あるいはメソッド) 全てに対してアノテーションを付けるのは,決して Less Configuration ではないと思います.

3.Annotation。これは今非常にハマって使ってます。

ハマってますねぇ.(^^;
いや,それが悪いとかいうつもりはないですよ.ただなんというか...
「麻疹みたいなもの©太一」
なのかなぁって感じちゃいます.ちょっとやりすぎ感が漂ってるような.
例えていうと,メークに興味を持ち始めたばかりの女の子があまりにも厚化粧しちゃってる,みたいな.(^^;;;
まぁ,誰でも一度は通る (通るべき) 過程なのかもしれませんけど.


典型的なのが 10/19 の「Seasar2.3でEJB3アノテーションを使ってみる」に出てくるコンポーネントの例.

@Components(namespace = "test1")
@Component(name = "client")
public class TestClientImpl implements TestClient {

独自の @Components アノテーションによりコンテナの名前空間を指定することができて,dicon ファイルがスッキリするのは分かります.
が,しかし.
これだと登録する全てのコンポーネントアノテーションを書かないといけないわけですよね.

ちょっとどうかと思うわけです.
もちろん,S2.3 の 〜ComponentAutoRegister と併用してもいいわけですが,それはしばし横へ.
これだと,コンテナの分割など構成を変更したくなったら大変じゃない?
例えばコンポーネントが 100 個登録されているコンテナがあるとして,つまり @Components(namespace = "test1") なんてアノテーションの付いたクラスが 100 個あるとして,それを二つのコンテナに (半々に) 分けようと思ったら,少なくとも 50 個のクラスを修正するのか,と.勘弁して〜.
それよりは,規約を決めて dicon でパターンマッチングする方がずっといいと思っちゃうんですよね.
そもそもコンポーネントがどのコンテナに属するかを知っているのは違和感あるし.


ほとんどの場合,数量的には

  • dicon ファイル <<< (越えられない壁) <<< クラス

となるわけで,少数の dicon をスッキリさせるために大量のクラスにアノテーション付けるのは本末転倒かな,と.
S2.2 以前で dicon ファイルに書いていたコンポーネント固有の情報をアノテーションで書けるようになるだけでは全然うれしくないんですよね.
そのアノテーションも所詮設定情報.dicon に書くのと五十歩百歩.


そんなわけで (どんなわけで?),コンポーネント一つ一つについて dicon を記述するのは避けたいけれど,単にアノテーションに置き換えればいいというものではないと思います.
重要なのはトータルの設定情報を減らすこと.
それには,たくさんあるものは個別に扱うのではなく集合で扱うのが有効.
つまり,規約重要.
S2.3 の場合だと,規約を決めてそれを 〜AutoRegister の設定として表現することで,個別のクラス毎の設定 (アノテーション含む) を無くすのが効果的ってことになるんじゃないかなぁ.
ともあれ (JW),クラスやメソッドに対するアノテーションというのは集合操作ではなく個別操作になりがちなので,決してファーストチョイスではないと思う次第です.


まぁ,アノテーションも使いようでは集合操作的にできるとは思いますけどね.
例えばインタフェースや抽象クラスに付けるアノテーション@Inherited とかもあることだし.
あるいはパッケージに付けるアノテーション.使ったことないけど.
なので,おいらも決してアノテーション撲滅委員会のメンバーということはありません.
でもでも,アノテーション乱用防止委員会のメンバーにはなっちゃうかも? (^^;


最後にまとめ.ひがさんの

設定ファイルを書きたいのか、書きたくないのか。

は,ちょっとだけ言い換えたい.
設定は (XML) ファイルだけではありません.アノテーションも設定です.
つまり,XML だろうがアノテーションだろうが,

設定を書きたいのか、書きたくないのか。

って感じ.このエントリのサブジェクトはこれです.
まぁ,アノテーションJava ソースファイルに記述するんだから設定ファイルでもあるわけですが.