この記事では、GoF(Gang of Four)が提唱する23のデザインパターンの一つであるFactory Methodパターンについて詳しく解説します。
Factory Methodパターンは、オブジェクト指向プログラミングでよく使用されるパターンで、オブジェクトの生成に関する設計を効率的に行う方法を提供します。
Java、C++、C#、VB.NETでの具体的な実装サンプルも含めて、理解を深めていきましょう。
Factory Methodパターンとは
Factory Methodパターンとは、オブジェクト生成をサブクラスに委譲することで、具体的なクラスに依存しないオブジェクト生成を可能にするデザインパターンです。
このパターンを使用することで、クライアントコードが特定のクラスに依存せず、インスタンス生成の責任を持つ「工場メソッド」を介してオブジェクトを生成することができます。
これにより、柔軟性が高まり、コードの再利用性や保守性が向上します。
Factory Methodパターンの背景
ソフトウェア開発において、異なるタイプのオブジェクトを生成する必要がある場合、通常は「new」キーワードを使って直接インスタンス化します。
しかし、こうしたアプローチは、具体的なクラスに依存してしまい、将来的な拡張や変更が難しくなります。
Factory Methodパターンは、オブジェクトの生成部分を分離し、抽象化することで、クラスの変更が必要な際でも柔軟に対応できるようにする設計手法です。
Factory Methodパターンの使い方
Factory Methodパターンの使用により、クラスを柔軟に拡張したり、新しいクラスを追加したりすることが容易になります。
以下に、パターンの基本的な構造を示します。
パターンの基本構造
- Product (製品クラス): オブジェクト生成のインターフェースを定義します。
- ConcreteProduct (具体的製品クラス): Productインターフェースを実装し、実際の製品を生成します。
- Creator (生成者クラス): Factory Methodを持つ抽象クラスで、具体的なProductの生成をサブクラスに委譲します。
- ConcreteCreator (具体的生成者クラス): Creatorクラスのサブクラスで、具体的なProductを生成するFactory Methodを実装します。
Factory Methodパターン実装サンプル
ここでは、Java、C++、C#、VB.NETの4つの言語でFactory Methodパターンの実装サンプルを紹介します。
それぞれの言語での実装を比較しながら、理解を深めてください。
Javaでの実装
// Productインターフェース
interface Product {
void use();
}
// ConcreteProduct
class ConcreteProductA implements Product {
public void use() {
System.out.println("Product Aを使用");
}
}
// Creatorクラス
abstract class Creator {
public abstract Product factoryMethod();
public void someOperation() {
Product product = factoryMethod();
product.use();
}
}
// ConcreteCreator
class ConcreteCreatorA extends Creator {
public Product factoryMethod() {
return new ConcreteProductA();
}
}
public class FactoryMethodExample {
public static void main(String[] args) {
Creator creator = new ConcreteCreatorA();
creator.someOperation();
}
}
C++での実装
#include <iostream>
using namespace std;
// Productクラス
class Product {
public:
virtual void use() = 0;
};
// ConcreteProductクラス
class ConcreteProductA : public Product {
public:
void use() override {
cout << "Product Aを使用" << endl;
}
};
// Creatorクラス
class Creator {
public:
virtual Product* factoryMethod() = 0;
void someOperation() {
Product* product = factoryMethod();
product->use();
delete product;
}
};
// ConcreteCreatorクラス
class ConcreteCreatorA : public Creator {
public:
Product* factoryMethod() override {
return new ConcreteProductA();
}
};
int main() {
Creator* creator = new ConcreteCreatorA();
creator->someOperation();
delete creator;
return 0;
}
C#での実装
using System;
// Productインターフェース
interface Product {
void Use();
}
// ConcreteProduct
class ConcreteProductA : Product {
public void Use() {
Console.WriteLine("Product Aを使用");
}
}
// Creatorクラス
abstract class Creator {
public abstract Product FactoryMethod();
public void SomeOperation() {
Product product = FactoryMethod();
product.Use();
}
}
// ConcreteCreatorクラス
class ConcreteCreatorA : Creator {
public override Product FactoryMethod() {
return new ConcreteProductA();
}
}
class Program {
static void Main(string[] args) {
Creator creator = new ConcreteCreatorA();
creator.SomeOperation();
}
}
VB.NETでの実装
' Productインターフェース
Public Interface Product
Sub Use()
End Interface
' ConcreteProduct
Public Class ConcreteProductA
Implements Product
Public Sub Use() Implements Product.Use
Console.WriteLine("Product Aを使用")
End Sub
End Class
' Creatorクラス
Public MustInherit Class Creator
Public MustOverride Function FactoryMethod() As Product
Public Sub SomeOperation()
Dim product As Product = FactoryMethod()
product.Use()
End Sub
End Class
' ConcreteCreatorクラス
Public Class ConcreteCreatorA
Inherits Creator
Public Overrides Function FactoryMethod() As Product
Return New ConcreteProductA()
End Function
End Class
Module Program
Sub Main()
Dim creator As Creator = New ConcreteCreatorA()
creator.SomeOperation()
End Sub
End Module
まとめ
Factory Methodパターンは、オブジェクト生成に関する柔軟性を提供し、クラスの具体的な実装に依存しない設計を可能にします。
Java、C++、C#、VB.NETそれぞれでの実装サンプルを通して、パターンの基本的な構造と利便性について理解を深められたかと思います。
今後、複雑なシステムや拡張性が求められるプロジェクトにおいて、Factory Methodパターンを活用することで、コードの保守性や再利用性が大幅に向上するでしょう。

