LoginSignup
17
11

More than 5 years have passed since last update.

Factory Methodに触れてみる

Last updated at Posted at 2015-12-12

今日の目標

JavaのFactory Methodに触れてみる

使うもの

ではスタート

はじめに

まずはおなじみ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

IMG_1604.JPG

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

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

17
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
11