Document

Seasar Conference
2006 Spring
今さら人には聞けないDI入門
2006.05.14
エスエムジー株式会社
小森 裕介([email protected])
© The Seasar Foundation and the others 2006. all rights reserved.
1
はじめまして!
•
•
•
•
名前:小森 裕介
Blog:http://d.hatena.ne.jp/y-komori/
所属:エスエムジー株式会社(http://www.smg.co.jp)
主な仕事:
–
–
–
–
Javaによる集中監視制御システム設計・開発
集中監視制御フレームワークの設計・開発
Webアプリケーションシステムの設計・開発
教育・各種執筆活動
• 「JAVA PRESS」
• 「日経ソフトウェア」「とことん作って覚える! Java入門」連載
• 「なぜ、あなたはJavaでオブジェクト指向開発ができないのか」
• Seasar2とのかかわり
– S2Containerコミッタ(PropertyInterType)、S2JMSコミッタ
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
2
はじめに
• どうも巷では「DIコンテナ」というのが
流行っているらしい・・・
• 興味はあるけど、ゆっくり勉強する時間ないし・・・
• どうせ今の仕事で使わないから、後回し・・・
そんなあなたに
40分でDIコンテナの魅力
お伝えします!
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
3
DIで何が楽になるのか?
• アプリケーションの変更が楽になる!
• アプリケーションのテストが楽になる!
• アプリケーションの再利用が楽になる!
生産性向上!
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
4
こんなコードにウンザリしていませんか?
たった3クラスの
依存でも・・・
TottemoTaihen
Before DI…
public class TottemoTaihen {
private DataSource ds;
private Logger logger;
private HitsuyouNaLogic logic;
コンストラクタ渡し
public TottemoTaihen(HitsuyouNaLogic logic) {
this.logic = logic;
DataSource
// データソースの取得
JNDIで取得
Context ctx = new InitialContext();
DataSource ds =
(DataSource)ctx.lookup("java:comp/env/jdbc/MySQL");
Logger
// ロガーの取得
this.logger = LoggerFactory.getLogger(this.getClass());
HitsuyouNaLogic
}
依存クラスの
準備がとってもタイヘン!
Seasar Conference
2006 Spring
public void doLogic() {
・・・本来の処理・・・
}
}
Factoryから取得
本当に書きたいの
は
ここだけなのに・・・
© The Seasar Project and the others 2006. all rights reserved.
5
DIならとってもカンタン!
After DI !!
public class DIdeKantan {
private DataSource ds;
private Logger logger;
private HitsuyouNaLogic logic;
public void doLogic() {
・・・本来の処理・・・
}
必要な処理のコーディングに
集中できる!
public void setDataSource(DataSource dataSource){
this.dataSource = dataSource;
}
public void setLogger(Logger logger) {
this.logger = logger;
}
public void setHitsuyouNaLogic(HitsuyouNaLogic logic) {
this.logic = logic;
}
}
Seasar Conference
2006 Spring
簡単なsetterメソッドを
用意するだけでOK!
© The Seasar Project and the others 2006. all rights reserved.
6
Before DI ・ After DI
Before DI…
TottemoTaihen
DataSource
必要なオブジェクトは
自分で準備するのが常識!
Logger Create!
HitsuyouNaLogic
必要なオブジェクトは
DI Container が
用意(Injection)してくれる!
だから、とってもタイヘン!
After DI !!
DI Container
DIdeKantan
DataSource
クラス本来の記述に専念できる!
Seasar Conference
2006 Spring
Logger
Injection!
HitsuyouNaLogic
© The Seasar Project and the others 2006. all rights reserved.
7
寿司にたとえるDI-非DIなちらし寿司
非DIなちらし寿司
•材料が多くて準備がタイヘン!
•材料が揃えば混ぜるだけなのに・・・
ソースコードにたとえれば・・・
えび
まぐろ
錦糸卵
いくら
Seasar Conference
2006 Spring
うに
にんじん
しいたけ
public class ちらし寿司 {
private 酢飯 sumeshi;
private まぐろ maguro;
private 錦糸卵 kinshiTamago;
private いくら ikura;
private えび ebi;
private うに uni;
private にんじん ninjin;
private しいたけ shiitake;
public ちらし寿司() {
酢飯準備();
まぐろ準備();
・・・省略・・・
しいたけ準備();
}
public void まぜる() {
酢飯の上に材料をちらす
}
private void 酢飯準備() {
・・・酢飯の準備・・・
}
private void まぐろ準備() {
・・・まぐろの準備・・・
}
・・・省略・・・
private void しいたけ準備() {
・・・しいたけの準備・・・
}
}
© The Seasar Project and the others 2006. all rights reserved.
8
寿司にたとえるDI-DIな手巻き寿司
DIな手巻き寿司
•寿司ネタは最初から用意されている
•あとは好きなものを巻くだけ!
ソースコードにたとえれば・・・
酢飯
まぐろ
厚焼き卵
きゅうり
えび
いくら
public class 手巻き寿司 {
private 酢飯 sumeshi;
private まぐろ maguro;
private 厚焼き卵 atsuyakiTamago;
private きゅうり kyuuri;
private えび ebi;
private いくら ikura;
public void 巻く() {
お好きにどうぞ!
}
「手巻き寿司」のつもり ↑
※ setter の記述は省略しています
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
9
現在利用できる代表的なDIコンテナ
• Spring Framework
– http://www.springframework.org/
– 世界的に有名
• Seasar2
– http://www.seasar.org/
– 世界的には、(今のところ)マイナー
– 純国産のプロダクト
– Spring には無い利点がいっぱい
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
10
DIコンテナは何をしてくれるのか?
• 必要なクラスをDIコンテナに登録しておくと、コンテナから
取り出すときに依存オブジェクトをセット(Injection)してくれる
設定(XML)ファイル
<components>
<component class=“DIdeKantan” />
<component class=“DataSource” />
<component class=“Logger” />
<component class=“HitsuyouNaLogic” />
</components>
DI Container
DIdeKantan
登録
Logger
DataSource
HitsuyouNaLogic
取得
① 対象オブジェクトの生成
② 依存オブジェクトの生成 がおこなわれる
③ 依存オブジェクトのセット
オブジェクトの生成はコンテナまかせ!
Seasar Conference
2006 Spring
DIdeKantan
DataSource
Logger
HitsuyouNaLogic
© The Seasar Project and the others 2006. all rights reserved.
11
DIのコンテナのもう一つの利点-AOP
• DIコンテナはオブジェクトを生成するだけでなく、
オブジェクトに動的な機能追加もできる
横断的に実現したい機能を
「アスペクト」として登録しておく
設定(XML)ファイル
<components>
<component class=“DIdeKantan”>
<aspect class=“TraceInterceptor” />
</component>
<component class=“HitsuyouNaLogic”>
<aspect class=“TraceInterceptor” />
</component>
</components>
DI Container
登録
コンテナから取得した時点で
機能が組み込まれている
•ソースコードの修正は一切不要!
•自動生成などの面倒な作業もなし!
Seasar Conference
2006 Spring
DIdeKantan
HitsuyouNaLogic
取得
DIdeKantan
HitsuyouNaLogic
ログ出力機能
ログ出力機能
More Info!
http://s2container.seasar.org/ja/aop.html
© The Seasar Project and the others 2006. all rights reserved.
12
「設計と実装の分離」の実現
• DIの世界では「設計と実装の分離」が本当に実現できる
<<interface>>
DIdeKantan
private HitsuyouNaLogic logic;
・・・
logic.foo();
・・・
HitsuyouNaLogic
HitsuyouNaLogicImpl
インターフェースに
依存
DI Container
<components>
・・・
<component class=“HitsuyouNaLogicImpl” />
・・・
</components>
実装クラスを登録
テスト用のモックオブジェクトを作った場合・・・
DI Container
<<interface>>
HitsuyouNaLogic
HitsuyouNaLogicImpl MockHitsuyouNaLogic
<components>
・・・
<component class=“MockHitsuyouNaLogic” />
・・・
</components> モックオブジェクトに変更
依存元(DIdeKantan)のソースコードは修正不要!
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
13
DI×AOPの威力
• DIとAOPの組み合わせでできること
設計と実装の分離
横断的な機能追加
– モックオブジェクトの提供
– 各種プーリングの実現
– トランザクションの実現
– 分散オブジェクトの実現 DI Container
元の実装クラス
・・・etc
どんな実装クラスを用意するかは
コンテナの設定次第!
テスト用モッククラス
利用側
元の実装クラス
利用する側からは
インターフェースしか見えていない
Seasar Conference
2006 Spring
各種アスペクト
適用
リモートオブジェクトを呼び出すスタブ
© The Seasar Project and the others 2006. all rights reserved.
14
デモ:DIでジャンケン!
• ジャンケンプログラムでDIの効果を体験しよう!
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
15
Strategyパターンで手の出し方を変える
ランダム
Player
Tactics
ComputerPlayer
ジャンケンの手を決める処理を
Tacticsへ委譲
実装クラスの変更を
DIコンテナで行う
Seasar Conference
2006 Spring
RandomTactics
StoneOnlyTactics
グーだけ
CyclicTactics
グー・チョキ・
パー
順番に
© The Seasar Project and the others 2006. all rights reserved.
16
Tacticsのインジェクション
ComputerPlayerクラス
public class ComputerPlayer extends PlayerImpl {
private Tactics tactics;
public int showHand() {
return tactics.readTactics();
}
S2Containerが自動的に
setterを呼び出してTacticsの
実装クラスをセットしてくれる
public void setTactics(Tactics tactics) {
this.tactics = tactics;
}
}
Tacticsの実装クラスを
意識する必要なし!
Seasar Conference
2006 Spring
Tacticsインターフェース
public interface Tactics {
public int readTactics();
}
© The Seasar Project and the others 2006. all rights reserved.
17
DIコンテナに対する5つのギモン
• 依存関係はどうやって判断するの?
– Seasar2なら、インターフェースに基づいて自動判断します
More Info!
http://s2container.seasar.org/ja/DIContainer.html#AutoBindingMode
• 結局設定ファイルをたくさん書くのでは?
– Seasar2なら、AutoRegisterでカンタンに登録!
More Info!
http://s2container.seasar.org/ja/DIContainer.html#ComponentAutoRegister
• 設定ファイルのデバッグが大変?
– Kijimuna(キジムナ)で記述の誤りがチェックできます!
More Info!
http://kijimuna.seasar.org/
• 結局はリフレクションでしょ、遅くないの?
– 独自のキャッシュ機構で速度低下はほとんどありません
– Seasar2はSpringと比較して2~300倍高速です
More Info!
http://s2container.seasar.org/ja/benchmark/20060412_seasar_vs_spring.pdf
• Setterを書くのが面倒くさい!
– PropertyInterType で setter いらず!
More Info!
Seasar Conference
2006 Spring
http://s2container.seasar.org/ja/aop.html#AOPInterType
© The Seasar Project and the others 2006. all rights reserved.
18
PropertyInterType でsetter不要!
public class DIdeKantan {
private DataSource ds;
private Logger logger;
private HitsuyouNaLogic logic;
public void doLogic() {
・・・本来の処理・・・
}
アノテーションの記述
のみでsetterを
動的に生成!
public class DIdeKantan {
@Propery
DataSource ds;
setterすら書きたくない!
@Property
private Logger logger;
public void setDataSource(DataSource dataSource){
this.dataSource = dataSource;
}
@Property
private HitsuyouNaLogic logic;
public void doLogic() {
・・・本来の処理・・・
}
public void setLogger(Logger logger) {
this.logger = logger;
}
public void setHitsuyouNaLogic(HitsuyouNaLogic logic) {
this.logic = logic;
}
}
}
※ PropertyInterType は S2Container 2.4.0 beta1 ~ 利用できます
※ S2Container 2.4 系では、EJB3.0 対応のため、さらに便利なフィールドインジェクションが利用可能になる予定です
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
19
DIコンテナの誤った使い方
• なんでもDIコンテナに放り込めばよい?
No!
– DIコンテナに登録するのは、
再利用可能な「コンポーネント」の単位
– どんな単位で登録するかは、きちんとした設計が必要
– Webアプリケーションならば、
DIベースの設計手法「Goya」を参考にするとよい
※ Goal Oriented Yielding Approach
Seasar Conference
2006 Spring
More Info!
『WEB+DB PRESS vol.31』 (技術評論社) 「Goyaで学ぶDIベースのシステム設計」
© The Seasar Project and the others 2006. all rights reserved.
20
DIコンテナの使いどころ
• DIコンテナのメリットはなんとなくわかった・・・
でも、
開発現場で
どう役立てればいいの?
DIコンテナの機能を
フルに使い切って設計するのは、
結構ムズカシイ!
そこで・・・
まずは、S2Containerを100%生かして作られた
周辺プロダクトを使ってください!
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
21
S2ファミリーを使ってみよう!
アプリケーション
Tuigwaa
代表的なS2ファミリー(Java)
ビジネスロジック
S2Hibernate
S2Dao
S2Buri
プレゼンテーション
S2Flex
S2JSF
(Teeda)
Mayaa
S2AOP S2Unit
Kijimuna
S2Javelin
S2JSF Plugin
分散技術
S2Struts
S2Tx
S2Axis S2RMI S2JMS
S2Remoting S2JCA
・・・他製品との連携を実現するもの
S2DBCP S2JDBC
S2Container
Seasar Conference
2006 Spring
開発用ツール
O/Rマッピング
・・・開発中プロジェクト
A
・・・本カンファレンスで取り上げられているもの
More Info!
http://www.seasar.org/products.html
© The Seasar Project and the others 2006. all rights reserved.
22
EJB3への潮流
• 「アンチEJB」として始まったDIコンテナの流れ
• DIコンテナの考え方は、EJB3の仕様に
取り込まれた
• Seasar2の弱点は「非標準」であること
Seasar2 2.4 ではEJB3に対応予定!
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
23
Seasar2をさらに知りたい方へ
• 『Seasar入門 ~はじめてのDI&AOP~』
–
–
–
–
–
税込価格:3,570円
出版社:ソフトバンククリエイティブ
ISBN:4797331968
監修:ひが やすを
著:須賀 幸次/木村 聡/西川 麗/高安 厚思/白井 博章/
椎野 峻輔/岡 薫/藤村 浩士
DIコンテナの基礎から
各種S2ファミリーの使い方まで
幅広く網羅
• Seasarの使い方に困ったら・・・
– Seasar-user メーリングリスト
• https://www.seasar.org/mailman/listinfo/seasar-user
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
24
ご質問について
スピーカーブースで
お待ちしています
気軽にお越しください
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
25
ご静聴
ありがとうございました
Seasar Conference
2006 Spring
© The Seasar Project and the others 2006. all rights reserved.
26