超簡易DIっぽいもの
今日のエントリでも書いたとおり、僕の考え方ってちょっとあれなので、
日本語にするとあまり意味が伝わりません。
で、こないだ友人にレクチャーしてもらった「DI入門」について、
それって結局こういうこと?なのをjavaソースで表現してみました。
Unitテストスーツとか、DIでこれがやりやすくなるよ的な
ものも書かないと「そういうこと」にならないかもしれないけど
とりあえず書いてみた。
てか、hatenaのソースコードハイライト記述を試してみたかった、
というのもあったりします。
intarface IFSayMessage
package ditest; public interface IFSayMessage { void sayMessage(); }
IFSayMessageの実装その1
sayGoodby
package ditest; public class sayGoodby implements IFSayMessage { public void sayMessage() { // You say good by. System.out.println("Good By"); } }
IFSayMessageの実装その2
sayHello
package ditest; public class sayHello implements IFSayMessage{ public void sayMessage(){ // and I say Hello. System.out.println("Hello"); } }
簡易DIコンテナContainer
なげぇ。汚ねぇ。
設定ファイル読むとこだけは別にすりゃよかった。
package ditest; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Node; public class Container { public static Object getNewInstance(final String _name){ Object obj = null; // ビルダー作成 // xmlとかあんま慣れてないから // ベタにDOMで読んじゃいますよ、と。 DocumentBuilder builder = null; try { builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); // 設定ファイルを変換します。 Document doc = null; doc = builder.parse("setting.xml"); // ノードを取得してfor分でサーチします。 NodeList list = doc.getElementsByTagName("useClass"); String classname = ""; Node node; for( int i=0 ; i < list.getLength() ; i++ ){ node = list.item(i); if( node.getNodeName() != "useClass" ){ // ノードの名前がuseClassじゃなかったら // 用がないので次のノードへ continue; } String setname; setname = node.getAttributes().getNamedItem("name").getNodeValue(); if( setname != "" && setname.equals( _name ) ){ classname = node.getAttributes().getNamedItem("className").getNodeValue(); } } // テストだし、遊びだし、面倒だからそのまま読ませちゃう。 // クラスが定義されてなかったらClassNotFoudとか言ってくれるでしょ。多分。 Class cls = null; obj = null; cls = Class.forName(classname); // インスタンスを生成してリターン // デフォルトコンストラクタのみ obj = cls.newInstance(); } catch (Exception e ){ // いや、仕事ではこんなこと決してしませんよ?;;; e.printStackTrace(); } return obj; } }
設定ファイルsetting.xml
<?xml version="1.0" encoding="Shift_JIS" ?> <!-- <useClass name="sayMessage" className="ditest.sayGoodby" /> --> <useClass name="sayMessage" className="ditest.sayHello" />
そして実行してみるMain処理
import ditest.*; /** * DIお試しメイン処理です。 */ public class Main { public static void main(String[] args) { for(int i = 0 ; i < 1000 ; i++ ){ IFSayMessage sayMessage = (IFSayMessage)Container.getNewInstance("sayMessage"); sayMessage.sayMessage(); try {//一秒待つ Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
設定ファイルを書き換えたら
実行クラスも変わってます。