Factory Methodに触れてみる

# 今日の目標
JavaのFactory Methodに触れてみる

# 使うもの
* [Java言語で学ぶデザインパターン入門](http://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030/ref=sr_1_1?ie=UTF8&qid=1449322953&sr=8-1&keywords=java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80)

# ではスタート

## はじめに
まずはおなじみWikipediaでFactory Methodを調べてみる。

>Factory Method パターン（ファクトリメソッド・パターン）とは、GoF (Gang of Four; 四人組)によって定義されたデザインパターンの1つである。 Factory Method パターンは、他のクラスのコンストラクタをサブクラスで上書き可能な自分のメソッドに置き換えることで、 アプリケーションに特化したオブジェクトの生成をサブクラスに追い出し、クラスの再利用性を高めることを目的とする。

あんまりピンと来ない。
参考にしている本によると、

> インスタンスを生成する工場をTemplete Methodパターンで構成したものが、Factory Methodパターンになります。

Templete Method + 大量生産ということ？
読み進めていると、どうやらTemplete MethodでFactoryクラスを作って、そのFactoryクラスの中で大量生産したいクラスをnewする流れのようです。

## 本のサンプルを参考にしてみる

工場クラスのTemplete。

``` Factory.java
package framework;

public abstract class Factory  {
	public final Building create(String material, String address) {
		Building b = createBuilding(material, address);
		registerBuilding(b);
		return b;
	}

	protected abstract Building createBuilding(String material, String address);
	protected abstract void registerBuilding(Building building);
}
```

工場クラスを実装したのが下のHouseFactory。

``` HouseFactory.java
package building;

import java.util.ArrayList;
import java.util.List;

import framework.Building;
import framework.Factory;

public class HouseFactory extends Factory {

	private static HouseFactory factory = new HouseFactory();

	private HouseFactory() {
		// privateコンストラクタ
	}
	public static HouseFactory getInstance() {
		return factory;
	}

	// 建物を建てた住所を登録する変数
	private List<String> addresses = new ArrayList<>();

	@Override
	protected Building createBuilding(String material, String address) {
		return new House(material, address);
	}

	@Override
	protected void registerBuilding(Building building) {
		addresses.add(((House)building).getAddress());
	}

	public List<String> getAddresses() {
		return addresses;
	}

}
```

作られる側の抽象メソッド。

``` Building.java
package framework;

public abstract class Building  {
	public abstract void live(String person);
}
```

作られる側の実装メソッド。

``` House.java
package building;

import framework.Building;

public class House extends Building {

	private String material;
	private String address;

	House(String material, String address) {
		System.out.println(material + "で" + address + "に作ります。");
		this.material = material;
		this.address = address;
	}

	@Override
	public void live(String person) {
		System.out.println(person + "が住みました。");
	}

	public String getAddress() {
		return address;
	}

}
```

```Main.java
import building.HouseFactory;
import framework.Building;
import framework.Factory;

public class Main {

	public static void main(String[] args) {
		Factory factory1 = HouseFactory.getInstance();
		Building house1 = factory1.create("木材", "東京都港区XXXXX");
		Building house2 = factory1.create("コンクリート", "東京都荒川区XXXXX");

		house1.live("斎藤さん");
		house2.live("佐藤さん");
	}

}
```

実行結果は下記のとおり。

```
木材で東京都港区XXXXXに作ります。
コンクリートで東京都荒川区XXXXXに作ります。
斎藤さんが住みました。
佐藤さんが住みました。
```

こういうことか。
![IMG_1603.JPG](https://qiita-image-store.s3.amazonaws.com/0/97937/1ccef750-f3d1-c308-b64c-2265fa35cb15.jpeg)

![IMG_1604.JPG](https://qiita-image-store.s3.amazonaws.com/0/97937/314a75c2-0a7c-2104-70e8-dbf6fe830988.jpeg)

とりあえず、使いたい側（Houseインスタンスがほしい側）はFactoryを見とけば良い！ということになるのかな。ちなみに、Factory実装クラスはいくつもインスタンスがなくても良いので、Factory実装クラスにSingletonパターンを混ぜてみました。

ということで、今回はFactory Methodパターンに触れてみました。