Help us understand the problem. What is going on with this article?

Factory Methodに触れてみる

More than 3 years have passed since last update.

今日の目標

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パターンに触れてみました。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away