📢 この記事は gemini-3-flash-preview によって翻訳されました
Simple Factory(単純工場)パターン
Simple Factoryパターンは生成に関するパターンに分類されるけど、GoFの23種類のデザインパターンには含まれないんだ。
定義:パラメータに応じて異なるクラスのインスタンスを返すことができる工場クラスを定義する。作成されるインスタンスは通常、共通の親クラスを持っているよ。
Simple Factoryパターンでインスタンスを作成するために使われるメソッドは通常、静的(static)メソッドなんだ。だから、Simple Factoryパターンは「Static Factory Method(静的工場メソッド)パターン」とも呼ばれているよ。
必要な製品に対応するパラメータを渡すだけで、その実装過程を知らなくても、必要な製品オブジェクトを手に入れることができるんだ。
例えば、ある餃子屋さんがあるとする。お客さんが特定の餃子を注文すると、店はその餃子を作ってお客さんに提供するよね。ここでは、餃子屋さんを「工場 (Factory)」、餃子を「製品 (Product)」、餃子の名前を「パラメータ」と見なすことができる。餃子屋さんはパラメータに応じて、異なる餃子を返してくれるってわけ。
例えば、お客さんが「ニラ餃子」を欲しがったら、「ニラ」がパラメータになる。餃子屋さんはそのパラメータに基づいて、ニラ餃子を返すんだ(店にニラ餃子のメニューがあることが前提だけどね)。

3つの役割:
- 工場(核心)
すべての製品を作成するための内部ロジックの実装を担当する。工場クラスは外部から直接呼び出され、必要なオブジェクトを作成するよ。
- 抽象製品
工場クラスが作成するすべてのオブジェクトの親クラス。製品オブジェクトの共通メソッドをカプセル化していて、具体的な製品はすべてその子クラスになるんだ。
- 具体的な製品
Simple Factoryパターンが作成する目標。作成されるオブジェクトはすべて、ある具体的なクラスのインスタンスだよ。
例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| public class SimpleFactory{
public static void main(String[] args){
Product productA = Factory.createProduct("A");
productA.info();
// ...
}
}
abstract class Product{
public abstract void info();
}
class ProductA extends Product{
@Override
public void info(){
System.out.println("A");
}
}
class ProductB extends Product{
@Override
public void info(){
System.out.println("B");
}
}
class Factory{
public static Product creatProduct(String type){
Product p = null;
// ここでは例外処理などは考慮していないよ
switch(type){
case "A":
p = new ProductA();
break;
case "B":
p = new ProductB();
break;
default:
System.out.println("Please try again");
break;
}
return p;
}
}
|
製品を追加したい時、工場クラスを書き換える必要があるから、これは 開放・閉鎖の原則 (Open-Closed Principle) に違反しちゃうんだよね。
Factory Method(工場方法)パターン
Factory Method Pattern。クラス生成に関するパターンだよ。
意図
オブジェクトを作成するためのインターフェースを定義し、どのクラスをインスタンス化するかは子クラスに決定させる。Factory Methodは、クラスのインスタンス化をその子クラスに遅延させるんだ。
構造

役割の説明:
- Product:工場メソッドが作成するオブジェクトのインターフェースを定義する。
- ConcreteProduct:Productインターフェースを実装する。
- Creator:工場メソッドを宣言する。このメソッドはProduct型のオブジェクトを返す。Creatorは工場メソッドのデフォルト実装を定義することもできて、それはデフォルトのConcreteProductオブジェクトを返す。工場メソッドを呼び出してProductオブジェクトを作成できるよ。
- ConcreteCreator:工場メソッドを再定義して、ConcreteProductのインスタンスを返す。
適用場面
Factory Methodパターンは次のような場合に適しているよ:
- クラスが、自分が作成しなければならないオブジェクトのクラスを事前には知らないとき。
- クラスが、作成するオブジェクトの指定を子クラスに委ねたいとき。
- クラスが、オブジェクト作成の責任を複数の補助子クラスのいずれかに委任していて、どの補助子クラスが代理人であるかという情報を局所化(隠蔽)したいとき。
例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| // 前のコードをベースに修正
public class FactoryMethod{
public static void main(String[] args){
Factory factoryA = new FactoryA();
//Product productA = Factory.createProduct("A");
Product productA = factoryA.createProduct();
productA.info();
// ...
}
}
// 抽象クラスをインターフェースに変更
// abstract class Product
interface Product{
// public abstract void info();
public void info();
}
// 継承を実装に変更
// class ProductA extends Product{
class ProductA implements Product{
@Override
public void info(){
System.out.println("A");
}
}
// 継承を実装に変更
// class ProductB extends Product{
class ProductB implements Product{
@Override
public void info(){
System.out.println("B");
}
}
// 実装クラスをインターフェースに変更
// class Factory
interface Factory{
public Product createProduct();
}
// インターフェースの実装を追加
class FactoryA implements Factory{
@Override
public Product createProduct(){
return new ProductA();
}
}
class FactoryB implements Factory{
@Override
public Product createProduct(){
return new ProductB();
}
}
|
Abstract Factory(抽象工場)パターン
Abstract Factory Pattern。オブジェクト生成に関するパターンだよ。
意図
具体的なクラスを指定することなく、関連し合う一連のオブジェクト、または依存し合う一連のオブジェクトを作成するためのインターフェースを提供するんだ。
構造

役割の説明:
- AbstractFactory:抽象製品オブジェクトを作成する操作のインターフェースを宣言する。
- ConcreteFactory:具体的な製品オブジェクトを作成する操作を実装する。
- AbstractProduct:ある種類の製品オブジェクトのインターフェースを宣言する。
- ConcreteProduct:対応する具体的な工場によって作成される製品オブジェクトを定義し、AbstractProductインターフェースを実装する。
- Client:AbstractFactoryとAbstractProductクラスで宣言されたインターフェースのみを使用する。
適用場面
Abstract Factoryパターンは次のような場合に適しているよ:
- システムが、製品の作成、構成、表現方法から独立している必要があるとき。
- システムを、複数の製品ファミリーのうちの1つで構成する必要があるとき。
- 関連する一連の製品オブジェクトをまとめて使用するように設計し、その制約を強調したいとき。
- 製品のクラスライブラリを提供し、その実装ではなくインターフェースだけを公開したいとき。
例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
| public class AbstractFactory{
public static void main(String[] args){
Factory factory1 = new Factory1();
ProductA productA = factory1.createProductA();
productA.info();
// ...
}
}
interface ProductA{
public void info();
}
class ProductA1 implements ProductA{
@Override
public void info(){
System.out.println("A1");
}
}
class ProductA2 implements ProductA{
@Override
public void info(){
System.out.println("A2");
}
}
interface ProductB{
public void info();
}
class ProductB1 implements ProductB{
@Override
public void info(){
System.out.println("B1");
}
}
class ProductB2 implements ProductB{
@Override
public void info(){
System.out.println("B2");
}
}
interface Factory{
public ProductA createProductA();
public ProductB createProductB();
}
class Factory1 implements Factory{
@Override
public ProductA createProductA(){
return new ProductA1();
}
@Override
public ProductB createProductB(){
return new ProductB1();
}
}
class Factory2 implements Factory{
@Override
public ProductA createProductA(){
return new ProductA2();
}
@Override
public ProductB createProductB(){
return new ProductB2();
}
}
|