超簡易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();
			}
		}
	}
}


実行結果。


設定ファイルを書き換えたら
実行クラスも変わってます。