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

id:da-yoshi:20051020#1129766161の内容に対して貴重なご意見を頂きました。


id:koichik:20051020#1129833013
反応ありがとうございます。正直、S2使い始めて1ヶ月そこらで、まだプロジェクト始まったばかりの状態の人間がどれだけ理解出来てるかということには非常に自信がなかったのですが(汗)、S2.3をせっかく真面目に検討したんだから、そこで自分が感じたことを書くことは決して無駄にはならないだろうと思って書いてみました。それが正しいかどうかはまた別として。
まずはご指摘いただいたネームスペースの例。よくよく考えると、自分は目的を少々混同していた気がします。そもそもの目的は「ある特定のアノテーションをつけたクラスを、コンテナに登録したい」というものでした。その為に、命名規約で設定するComponentAutoRegisterに依存しない方法を探す・・・という方向で色々試していたのですが、そのことと「定義の分割、ネームスペース定義を、componentタグにクラス名を記述する以外の方法で実現する」という目的は本来別のもので、分けて考えるべきだったと思います。実は@Componentsタグをつけたクラスを見た瞬間「これは、クラスに置くにはちょっと余計な情報じゃないか?」と思ってしまったのは事実です(汗)
自分がid:da-yoshi:20051020#1129766161で書いた

「このメタ情報はクラスに置くべきか、ファイルで一括定義すべきか」

の視点で考えた時に、そもそもクラスのネームスペース情報というのは元々「パッケージ」(C#なら「ネームスペース」というそのものズバリの名前になってますが)というものが存在しているのだから、コンポーネントのグループ分け情報はパッケージで行うのがベストであり、パッケージに紐づかない別のネームスペース情報を持つことがそもそも冗長ではないのか?・・・ご指摘を受けて色々考えてる中で、そんな考えが出てきました。そう考えると、ネームスペース定義については、
「クラスが本来持っているパッケージ情報に基づいて、その中で一つのコンテナとしてまとめたい単位で、クラスパターンのパッケージに指定して、ComponentAutoRegisterで設定する方が望ましい」
という結論になるのかな? 例えば、あるWebアプリでログイン業務を行う部分を一つのコンテナ定義にまとめたい場合

hoge.login.action
hoge.login.logic
hoge.login.dao

みたいなパッケージが存在したとして、そのクラスにパッケージとは無関係の「namespace」という情報が存在するのではなく、「hoge.login」という単位で自動的にグループに属するという方が、最終的にクラスに紐づく情報が少なくなって良い・・・ということですね。
さて、ここで自分の本来の目的だった「ある特定のアノテーションをつけたクラスを自動的にコンテナに登録する」ですが、これは元々@Entityを意識してました。次の日記で書こうと思っていたことですが・・・
id:da-yoshi:20050919#1127140225でHibernate Annotationsに触ってみたのですが、その中で、hibernate3.cfg.xmlにクラス名を登録する必要がありました。せっかく@Entityというアノテーションがあるのだから、これをつけたクラスを自動的にHibernateに登録したいと思ったんです。
あと、@Entityのクラス名をDBのテーブル名と同じにすれば、@Tableアノテーションを書く必要が無くなり、一つアノテーションが消えます。これも一つの命名規約ですが・・・
ここらへんから「クラス名の命名規約でではなく、特定アノテーションをつけたクラスを自動的にコンテナに登録したい」という考えに繋がっていったんですが・・・よくよく考えると、@Entityを登録するのはあくまでHibernate等のO/Rマッピングツールであり、DIコンテナじゃ無いんだよなぁ(汗)・・・もしかして、これもそもそも自分の勘違いか?(大汗)・・・
なんか、自分で考えをまとめればまとめるほど苦しくなってきましたが(汗)、@Entityを意識していたから「クラスの命名規約同士がぶつかる」という状態を懸念する方向に傾いていったのは事実です。だったら、@Componentというアノテーションもあることだし、EJB3では@Statelessやらなんちゃら色々あるみたいだし(苦笑)、クラスの最終登録に関しては、アノテーションによって判断して、アノテーションによって様々な登録形態があっても便利かなぁと思いました。さっきの@Entityについては、初期化時に探し出して自動的にO/Rマッピングツールに登録するような機能は最低限欲しいですし。
あと、トランザクションアノテーションについてですが、これは今のプロジェクトでの「教育」の体験から今の考えに至ってます。元々自分は普通にS2のdiconに定義を書くつもりだったのですが、上の方から「設定ファイル記述が多すぎるんじゃないか?」という懸念を受けてしまいまして、その懸念がクリア出来ないとS2の採用そのものが却下されそうな状態でした。それで慌てて色々調べて、例のアノテーションを使う手法に辿り着いた・・・という歴史がありました(汗)


(追記)本音を言えば、DIコンテナに関わらずオープンソースフレームワーク・ライブラリについては、使う側は極力手を入れずに、(基本機能でどうしても出来ないこと以外は)デフォルトのままで使う方が本当は好きです。教育するときに「S2勉強しといてください」の一言で済むし、開発者側もデフォルトで勉強してローカルルールがあまり無い方が後々のことを考えると役に立つ筈ですし・・・ただ、一度やってしまった以上、やってしまった方向性については、しっかり考えていくべきかなと今は思ってます。


話を戻しまして・・・実際開発担当の皆さん(ほとんどがDIコンテナ未経験の方でした)に作り方を説明したところ、アノテーションを使ってトランザクション等の処理をやるところが、非常にすんなりとわかって貰えたのが意外というか、予想外でした。(ちなみに、自分は他に、エラー処理時に担当者にメールを投げるInterceptorとか作って、これもアノテーションで定義するようにしてます、エラーメールのテンプレートに「$error処理時にエラーが発生しました」みたいな文言があるのですが、そこにはアノテーションから情報を渡してあげて、何の処理でエラーが起こったのかわかるようにしてます。余談でした)どうも、ソースを直接書く側からみれば、@Transaction等の記述が視覚的で、結構わかりやすかったみたいです。
↑のような経験があったので、実際に作る立場の人達のことを考えれば、アノテーションを「適切で分かり易い名前で、情報が重複しないように」定義してやれば、非常に助けになるのではないか?・・・と今は感じてます。それと、今後EJB3が出てくれば一時的にアノテーションの氾濫が発生する状態も考えられるし、だったら今のうちから積極的にアノテーションについて検討しておいて、果たして本当にこれで便利になるのか、危ない部分は無いのか、見極めるのも無駄ではないのではないのかな?・・・と・・・いや、これは単に自分の現在の行動の正当化だな(汗)
おっしゃられるとおり、単に今が「麻疹みたいなもの」の状態なのかも知れないし(いやかなりの確率でそうかも?(汗))、まぁでも一通りプロジェクトが終わる頃には体感として実感出来る筈だから・・・そのとき改めてアノテーション使った開発の感想は書いてみたいと思います。・・・あ、でも今のプロジェクトで使ってるアノテーションはせいぜい2つ、3つだから、自分の経験だけで「アノテーションは良い」という結論にも至らないか・・・うーむ・・・
(追記)書き忘れてましたが、@Inheritedアノテーションは、インターフェイスに関しては無効なんですよね。「インターフェイスに一回だけアノテーションを定義して、実装クラスは何も無し」みたいな定義がJavaでは出来なくて(C#ではどうか知らないんですけど)、ここは非常に不満です。たしかに、今のアノテーションの機能では、どうしても「アノテーションの記述そのものが開発規模に比例して増大してしまう」という欠点は避けられないのかなと思います。