読者です 読者をやめる 読者になる 読者になる

感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

入門的サンプルを作ってみた。

<スポンサーリンク>

■Springの利点
・実行に必要なクラスの準備をSpringが行ってくれる

・それによって、オブジェクト間が疎結合となる。

・疎結合になって、依存性が弱まることによって、変更に強くテストが容易で、コンポーネントの再利用性が高い柔軟なアプリケーションを作成することができる。

・クラス間の結びつきが強すぎると、依存するクラスを変更した場合にコードの修正が広範囲におよぶ可能性が生じる。

・インターフェースと実装を分離するコーディングを行うことで、インターフェースさえ変更しなければ、たとえ実装を変更したとしても利用する側が受ける影響を最小限に抑えることができる。

・インターフェースで定義されているメソッドは、そのインターフェースを実装するすべてのクラスで実装されていることが保証できるため、変更対象のオブジェクトを利用する側はメソッド呼び出しのコードを変更しなくてもよくなる。

★★
Springは「DIコンテナ」と呼ばれる。
一個前の記事にも書いたが、DIコンテナはインスタンスの作成とか、プロパティの設定とかをDIコンテナがやってくれる。

そうすることで、プログラマはソースの中にnewを書いたり、セッターに値を設定するようなコードを書かなくても済むようになる。
定義すれば、DIコンテナが勝手に値を注入してくれるからだ。

DIの[I]は「注入」という意味である。

Dependancy Injection。「依存性を、注入する」。オブジェクト指向プログラマーにとって心地良い響きのこの単語は、文字通りクラス間の依存性をDIコンテナが代わりに請け負ってくれることで、疎結合な設計を可能にする。

たとえば、人を表すこのインターフェース。
インターフェースに定義されているのは、自己紹介する振る舞い、挨拶をする振る舞いである。

package sample3;

public interface Person {
	/** 自分の名前を紹介する */
	public void introduceMySelf();
	/** 挨拶をする */
	public void sayHello();
}

で、上記のインターフェースを実装したクラスはこんな感じだ。

package sample3;

public class PersonImpl implements Person {
	private String name;
	private String message;
	public void setName(String name) {
		this.name = name;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	
	public void introduceMySelf() {
		System.out.println("My name is " + name);
	}
	public void sayHello() {
		System.out.println( message + " I'm " + name );
	}
}

さて、このPersonImplというクラスを使う「HowAreYou」クラスを作ってみる。
他のクラスを使うということは、newして、上にある「name」とか「message」に値をセットしなければいけないように思える。

しかし、そういうのは全部DIコンテナもとい、Springがやってくれる。
PersonImplを使うソースはこんな感じだ。

package sample3;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class HowAreYou {
	public static void main(String[] args) {
		BeanFactory factory = new XmlBeanFactory(new
				FileSystemResource("beans.xml"));
		Person person = factory.getBean("person", PersonImpl.class);
		person.introduceMySelf();
		person.sayHello();
		
		System.out.println("--------------------------");
		//クラスの再利用が超簡単になる!
		Person takaki = factory.getBean("takaki", PersonImpl.class);
		takaki.introduceMySelf();
		takaki.sayHello();
	}
}

これで実行すると、ちゃんとこんな結果が出てくる。

My name is Mizky
Hello I'm Mizky
My name is Takaki
Good Morning I'm Takaki

なぜ、ソースのどこにも書いていない「Mizky」や「Takaki」が表示できたのか。
その秘密はbeans.xmlにある。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	<bean id="messageBean" class="sample2.MessageBeanEn" />
	<bean id="person" class="sample3.PersonImpl" >
		<property name="name">
			<value>Mizky</value>
		</property>
		<property name="message">
			<value>Hello</value>
		</property>
		
	</bean>
	<bean id="takaki" class="sample3.PersonImpl" >
		<property name="name">
			<value>Takaki</value>
		</property>
		<property name="message">
			<value>Good Morning</value>
		</property>
		
	</bean>
</beans>

ここのidに名前を設定している。getBeanで指定する名前を。xmlに"takaki"とか"person"とあるのがそれだ。
で、propertyに指定するのは、セッターにインジェクション、つまりセッターに代入する値だ。
classには、インスタンス化するクラスが指定されている。

つまり、定義ファイルにこれらの情報を書いておけば、「使う側」は「使われる側」をインスタンス化せずに使うことができる。

そうすることで、使う側(HowAreYou)と使われる側(PersonImpl)の結合を疎結合にすることができるのだ。
疎結合というと、変更に強く、柔軟なアプリケーションができる。影響範囲を特定しやすく、変更が他のクラスに影響しづらくなるからだ。

そんな感じで、「SpringによるWebアプリケーション スーパーサンプル 第2版」の1章目をやってみた。
この本は初心者に非情に優しい本だ。DIっぽいのを1時間で動かして見ることができた。

次から2章目の学習を進めたい。
こうやって実際に作ることで、だんだんとSpringがわかってくるような気がしている。
「スーパーサンプル」と「Spring3入門」を併用して読むことで、色々相互補完してくれていて良い感じに学習を進めることができる、気がしている。

SpringによるWebアプリケーションスーパーサンプル 第2版

SpringによるWebアプリケーションスーパーサンプル 第2版