デザインパターンの雑談(9)~ファクトリーメソッドパターン
- コラム紹介
- ファクトリメソッドパターン
-
- 役割分類
- 本旨
- Java コードの実装:
-
- 乗用車や SUV など、さまざまな種類の車を生産できる自動車工場があるとします。まず、抽象車クラス (AbstractProduct) を定義します。
- 次に、特定の自動車クラス (ConcreteProduct1) と SUV クラス (ConcreteProduct2) を定義します。これらは両方とも抽象自動車クラスから継承します。
- 次に、自動車を作成するための抽象メソッドを含む抽象自動車ファクトリー クラス (AbstractFactory) を定義します。
- 次に、特定の自動車ファクトリー クラス (ConcreteFactory1) と SUV ファクトリ クラス (ConcreteFactory2) を定義します。これらはどちらも抽象自動車ファクトリー クラスから継承します。
- 最後に、クライアント コードでファクトリ メソッドを使用して、車オブジェクトを作成します。
- 出力結果は、
- 分析する
- メリットとデメリットの分析
コラム紹介
カラムアドレス
コラム紹介
主に現在市場に出回っている23種類の一般的なデザインパターンを一つ一つ分析してまとめていますので、興味のある方はぜひご覧ください、また随時更新していきます。皆さんが私を監督し、一緒に学び、進歩できることを願っています。
ファクトリメソッドパターン
ファクトリ メソッド パターンは、オブジェクトを作成するためのインターフェイスを定義する作成用のデザイン パターンですが、どのクラスをインスタンス化するかはサブクラスによって決定されます。ファクトリ メソッド パターンは、オブジェクトのインスタンス化をサブクラスに延期します。
役割分類
抽象的なプロダクト
これは製品のインターフェイスを定義し、共通の親クラスまたは特定の製品クラスのインターフェイスです。
コンクリート製品
抽象製品インターフェイスを実装する具象クラス。
抽象的な工場
製品を作成するための 1 つ以上の抽象メソッドを含む、製品を作成するためのインターフェイスを定義します。
コンクリート工場
これは抽象ファクトリ インターフェイスを実装し、特定の製品のインスタンス化を担当します。
本旨
オブジェクトの作成と使用を分離することで、クライアントは特定の製品を直接インスタンス化するのではなく、ファクトリ メソッドを呼び出すことによってオブジェクトを作成します。この利点は、クライアントは、特定の製品の詳細を気にすることなく、抽象的な製品と抽象的なファクトリーの存在だけを知る必要があることです。さまざまなタイプの製品を作成する必要がある場合、クライアント コードを変更せずに、対応する特定の製品と特定のファクトリを実装するだけで済みます。
Java コードの実装:
乗用車や SUV など、さまざまな種類の車を生産できる自動車工場があるとします。まず、抽象車クラス (AbstractProduct) を定義します。
public abstract class Car {
public abstract void drive();
}
次に、特定の自動車クラス (ConcreteProduct1) と SUV クラス (ConcreteProduct2) を定義します。これらは両方とも抽象自動車クラスから継承します。
public class SedanCar extends Car {
@Override
public void drive() {
System.out.println("Driving sedan car...");
}
}
public class SUV extends Car {
@Override
public void drive() {
System.out.println("Driving SUV...");
}
}
次に、自動車を作成するための抽象メソッドを含む抽象自動車ファクトリー クラス (AbstractFactory) を定義します。
public abstract class CarFactory {
public abstract Car createCar();
}
次に、特定の自動車ファクトリー クラス (ConcreteFactory1) と SUV ファクトリ クラス (ConcreteFactory2) を定義します。これらはどちらも抽象自動車ファクトリー クラスから継承します。
public class SedanCarFactory extends CarFactory {
@Override
public Car createCar() {
return new SedanCar();
}
}
public class SUVFactory extends CarFactory {
@Override
public Car createCar() {
return new SUV();
}
}
最後に、クライアント コードでファクトリ メソッドを使用して、車オブジェクトを作成します。
public class Client {
public static void main(String[] args) {
CarFactory factory1 = new SedanCarFactory();
Car sedanCar = factory1.createCar();
sedanCar.drive();
CarFactory factory2 = new SUVFactory();
Car suv = factory2.createCar();
suv.drive();
}
}
出力結果は、
Driving sedan car...
Driving SUV...
分析する
ファクトリ メソッド パターンを使用すると、クライアント コードは、特定の製品の作成プロセスを考慮することなく、抽象製品および抽象ファクトリと対話するだけで済みます。他のタイプの自動車を追加する必要がある場合、クライアント コードを変更せずに、対応する特定の製品と特定のファクトリーを実装するだけで済み、コードの拡張性と保守性が実現されます。
メリットとデメリットの分析
アドバンテージ
開閉原則を遵守する
ファクトリ メソッド パターンは、抽象ファクトリと具象ファクトリの概念を導入することにより、システムの拡張性を高めます。新しい製品を追加する必要がある場合、既存のコードを変更することなく、対応する特定の製品と特定の工場を追加するだけで済みます。これは、開閉の原則と一致しています。
オブジェクト作成プロセスをカプセル化します。
クライアントは抽象的な製品と抽象的な工場のみを気にする必要があり、特定の製品の作成プロセスについて気にする必要はありません。特定の製品の作成プロセスは特定のファクトリーにカプセル化され、クライアント コードがより簡潔で読みやすくなります。
クライアントと特定の製品の間の結合を軽減します
クライアントは、特定の製品ではなく、抽象的な製品と抽象的なファクトリーのみに依存します。これにより、クライアント コードを特定の製品から分離し、コードの柔軟性と保守性を向上させることができます。
特定のファクトリ クラスは、設定ファイルなどを通じて動的に指定できます。
ファクトリメソッドパターンは、設定ファイルやリフレクションなどを通じて特定のファクトリクラスを動的に指定することができ、より柔軟なオブジェクト作成方法を実現します。
欠点がある
システムの複雑さが増す
抽象ファクトリーと具体ファクトリーの概念の導入により、システムの構造はより複雑になります。システム内の製品が少数しかない場合、ファクトリ メソッド パターンの使用は保守や理解が困難すぎるように見えるかもしれません。
コード量が増えた
ファクトリメソッドパターンでは、抽象プロダクト、具象プロダクト、抽象ファクトリ、具象ファクトリなどの複数のクラスを定義する必要があり、コード量が増加します。単純なプロジェクトの場合、ファクトリ メソッド パターンの使用は冗長に見えるかもしれません。
クライアントは特定のファクトリ クラスを知る必要があります
クライアントは特定のファクトリ クラスの存在を知る必要があるため、クライアントの依存関係が増加します。特定のファクトリ クラスの作成ロジックが変更された場合は、それに応じてクライアント コードも変更する必要があります。