凪瀬 Blog
Programming SHOT BAR

目次

Blog 利用状況
  • 投稿数 - 260
  • 記事 - 0
  • コメント - 46605
  • トラックバック - 192
ニュース
広告
  • Java開発者募集中
  • 経歴不問
  • 腕に自信のある方
  • 富山市内
  • (株)凪瀬アーキテクツ
アクセサリ
  • あわせて読みたい
凪瀬悠輝(なぎせ ゆうき)
  • Java技術者
  • お茶好き。カクテル好き。
  • 所属は(株)凪瀬アーキテクツ
  • Twitter:@nagise

書庫

日記カテゴリ

 

今回はDIコンテナの拡張について考えたいと思います。かつのりさまの DIコンテナまとめ を踏襲しています。

私の主張は一言でいえば、「DIはnew演算子へのAOPで表現できる」というものです。ここでいうDIは依存性の注入(Dependency Injection)、 AOPはアスペクト指向(Aspect-Oriented Programming)のことです。

DIを用いたインスタンス生成は、オブジェクトの初期化という横断的関心事(Cross-Cutting Concerns、)を取り扱っていると私は捉えました。
DIを用いるシーンというのがオブジェクト生成に限定されます。多種多様な場所でのオブジェクト生成に対して、依存性の注入を行うわけですが、これこそアスペクト指向で取り扱われる横断的関心事の一例であると捉えたのです。

DIコンテナの実現を考える場合、new演算子もしくはコンストラクタに対して依存性の注入処理をウィービング(Weaving)することで実現可能なはずです。
これを逆に捉えると、あらゆる箇所のあらゆるオブジェクトの生成に対し、 DIによる依存性の注入が可能ということになります。

通常、DIが活用される箇所としてはオブジェクトのライフサイクルが長い場所が選ばれます。分かりやすいのはsingletonインスタンスによるリソース管理クラスといったものです。こうしたオブジェクトには静的なパラメータ設定で初期化をすれば事足ります。
new演算子にウィービングしてDIを行うのであれば、多分、静的なパラメータでは足りません。今のソースコード上でのthisポインタからプロパティを設定するといった、より動的なパラメータによる初期化がしたくなると思うのです。

これは、コンストラクタ引数にthis.getXXX()といったプロパティを渡してオブジェクトを生成するような部分を外部設定ファイルに掃きだすことで疎結合化しようという試みになるのではないでしょうか。

このような機能性があったとして、どのような応用例があるのか、実はよくわかりません。既存のDIコンテナでも、FactoryオブジェクトをDIで生成することで似たようなことは出来るのではないかと思います。

DIを使ったデザインパターンを収集・整理して見ると活用方法が見出せるような気もします。

投稿日時 : 2007年8月29日 19:07
コメント
  • # re: DIコンテナの拡張について考える
    かつのり
    Posted @ 2007/08/29 19:54
    IoCを使わないDIのパターンって感じでしょうか。

    つまり、DIコンテナのまとめのエントリの例でいうと、
    Car car = new Car();
    でcarにはTireやEngineが注入された状態でインスタンス生成されるという感じ・・・?
    これは以前考えたこともあります。

    ドメインオブジェクトとの相性はいいかもしれません。
    new Hoge()でDAOやらトランザクションが注入されると非常に楽です。

    ところがコンストラクタへのAOPは、実際にはかなり苦労します。
    それはJavaが必ず親クラスのコンストラクタを先に呼ぶか、
    自身のクラスのコンストラクタを呼び出す必要があるからです。

    依存解決した上での別コンストラクタへのディスパッチが制限されるので、
    自由が利かないのと、既存のクラスの利用が難しくなると思います。。。

    JavassistのCtConstructorではsuper/thisの呼び出しが自動的に挿入されます。
    無理やりsuper/thisの呼び出しを遅らせることって出来るんだろうか・・・
    バイトコードを直接いじれば可能かもしれませんが、
    それがJava言語ではなく、VM的にOKなのかはちょっと調べないと分かりません。
  • # re: DIコンテナの拡張について考える
    凪瀬
    Posted @ 2007/08/29 20:53
    現在のカレントスレッドの通過しているコードポイントでのthisってのは実際難しいでしょうね。
    シンタックスシュガー的な対応でもないと無理かも。
    例えば無名クラスなどにthisオブジェクトを暗黙に渡すような仕掛け。

    実装の可能性と、それとは別にプログラミングパラダイム的な可能性とを分けて考えないといけませんね。

    想定できる利用例はやはりドメインオブジェクトへのDAO挿入などですかね。
    木構造に沿ってきれいにオブジェクトが配分されると良い感じ。
  • # re: DIコンテナの拡張について考える
    かつのり
    Posted @ 2007/08/29 21:06
    あのAspectJでもコンストラクタへAOPを適用すると、
    superもしくはthis呼び出しの後に
    beforeアドバイスが実行されます。

    多分VM的にはメソッドとコンストラクタの区別がないと思うんですが、
    かといって怪しいバイトコードを生成しても、
    JITの最適化を阻害してしまうので、これは厳しいですね。

    DIを使うと、DIコンテナから直接インスタンスを取得するってケースが
    実際にはほとんどないので、
    この辺はnewの部分で無理しなくてもいいのかなと。
  • # re: DIコンテナの拡張について考える
    凪瀬
    Posted @ 2007/08/30 10:44
    ウィービングするにしてもポイントカットはコンストラクタの後ろ側でしょうね。

    そもそも
    public Constractor(int param) {
     super();
     this.param = param;
    }
    みたいにsuper()してから引数をフィールドに格納するわけですからね。
    このthis.param = param;部分をDIコンテナに移してしまうとどうか、ということですから。
    そうすると、デフォルトコンストラクタでインスタンス生成してsetterでパラメータ設定するのと変わらないでしょう?
  • # re: DIコンテナの拡張について考える
    かつのり
    Posted @ 2007/08/30 10:58
    スーパークラスが引数なしのコンストラクタを持っているときにちょっと大変かなと。
    スーパークラスのコンストラクタの依存性解決も行うのはちょっとキツイでしょう・・・
    この辺を動的に解決するのは、コンストラクタの外側からしか
    無理じゃないでしょうか。

    自分自身だけの依存性解決ならsuper呼び出しの後で十分なんですが、
    コンストラクタはsuper呼び出しが先というルールに泣かされます。
  • # re: DIコンテナの拡張について考える
    凪瀬
    Posted @ 2007/08/30 14:14
    スーパークラスに対してもDI注入ですか!
    DIの注入も継承階層を辿りながら行う必要がある?

    むしろ、デフォルトコンストラクタなのであれば、
    スーパー実装の部分に対しても別途setterで初期化すれば済む話だと思うのですが、
    引数付きだとインスタンス生成に制約があってDIコンテナでオブジェクト生成というのが
    非現実的になってしまうのかもしれないな、と思いますが…。

    DI前提のクラスってコンストラクタに処理かいちゃまずいのかな…。
  • # KwRXlYERERT
    http://www.kosherbeefjerky.com/
    Posted @ 2012/01/04 6:02
    55V9ni 52. "The road will be overcome by that person, who goes." I wish you never stopped and be creative - forever..!
タイトル
名前
Url
コメント