ファクトリ メソッド パターン。仮想コンストラクタ パターンまたはポリモーフィック ファクトリ パターンとも呼ばれます。
1. 目的:オブジェクトを作成するためのインターフェイスを定義し、どのクラスをインスタンス化するかをサブクラスに決定させます。ファクトリ メソッドは、クラスのインスタンス化をそのサブクラスに延期します。
(オブジェクトを作成するためのインターフェイスを定義しますが、どのクラスをインスタンス化するかはサブクラスに決定させます。ファクトリ メソッドを使用すると、クラスのインスタンス化をサブクラスに延期できます。)
2. 参加者:
• 抽象プロダクト (Product):ファクトリ メソッドによって作成されるオブジェクトのインターフェイスを定義します。
• 具体的な製品:抽象的な製品のインターフェイスを実装します。
• Abstract Factory (Creator):抽象製品タイプのオブジェクトを返すファクトリ メソッドを宣言します。抽象ファクトリは、デフォルトの具体的な製品オブジェクトを返すファクトリ メソッドのデフォルト実装を定義することもできます。ファクトリ メソッドを呼び出して、抽象製品オブジェクトを作成できます。
• Concrete Creator:ファクトリ メソッドを再定義して、具体的な製品インスタンスを返します。
3. 構造:
次のように、実際の例を使用してファクトリ メソッド パターンの定義をマップします。
一汽フォルクスワーゲン (抽象工場) は多くのモデルの自動車 (抽象製品) を生産しており、そのうちの 1 つであるアウディ A6 (具体的な製品) は、アウディ A6 生産工場 (具体的な工場) によって生産されています。
ファクトリ メソッド パターンを使用して、前の記事「初心者のための Java デザイン パターンに関するメモ - 簡単なファクトリ パターン」の例 6の要件を実現する場合、次のようになります。
一汽フォルクスワーゲン (工場部門) は2 台の車 (抽象製品) を生産しました。1台はAudi A6 (具体的な製品)と呼ばれ、もう 1 台はAudi A8 (具体的な製品) と呼ばれます。
次に、上記の要件の説明を次のように少し変更する必要があります。
一汽フォルクスワーゲン (抽象工場) は2 台の車 (抽象製品)を生産し、1 台はアウディ A6 (具体的製品)と呼ばれ、アウディ A6工場(具体的工場)で、もう 1 台はアウディ A8 (具体的製品) と呼ばれ、生産されます。アウディ製 A8工場(特定工場)で。
Java コード実装の例 7は次のとおりです。
車 (抽象的な製品の役割):
/*
* 无论哪个工厂生产的汽车,都是汽车 (抽象产品类)
*/
public abstract class Car {
public String name;
}
Audi A6 (特定の製品の役割):
/*
* 奥迪A6,是一汽大众生产的一款汽车 (具体产品类)
*/
public class AudiA6Car extends Car {
public AudiA6Car(){
this.name = "奥迪A6";
}
public String toString(){
return "一辆"+ this.name;
}
}
Audi A8 (特定の製品の役割):
/*
* 奥迪A8,是一汽大众生产的一款汽车 (具体产品类)
*/
public class AudiA8Car extends Car {
public AudiA8Car(){
this.name = "奥迪A8";
}
public String toString(){
return "一辆"+ this.name;
}
}
一汽フォルクスワーゲン (抽象的な工場の役割):
一汽フォルクスワーゲン、工場から抽象工場へ役割を変える
/*
* 抽象工厂角色,使用接口来定义
*/
public interface CarFactory {
/*
* 生产汽车的工厂方法
*/
public Car manufactureCar();
}
アウディ A6 生産工場 (特定の工場の役割):
新しい特定のファクトリ ロールを作成しました
/*
* 具体工厂(Concrete Factory)角色
*
* 生产奥迪A6的工厂
*/
public class AudiA6CarsFactory implements CarFactory {
/*
* 生产汽车的工厂方法
*/
public Car manufactureCar() {
// 奥迪A6
return new AudiA6Car();
}
}
アウディ A8 生産工場 (特定の工場の役割):
新しい特定のファクトリ ロールを作成しました
/*
* 具体工厂(Concrete Factory)角色
*
* 生产奥迪A8的工厂
*/
public class AudiA8CarsFactory implements CarFactory {
/*
* 生产汽车的工厂方法
*/
public Car manufactureCar() {
// 奥迪A8
return new AudiA8Car();
}
}
コードのクラス構造は次のとおりです。
クライアントの呼び出し:
顧客 A (クライアント) は Audi A6 の購入を希望し、顧客 B (クライアント) は Audi A8 の購入を希望しています。
クライアント側の呼び出し方法も変更されており、最初に特定のファクトリ オブジェクトを作成する必要があります。
public class Customers {
public static void main(String[] args){
// 实例化生产奥迪A6的工厂
CarFactory audiA6CarFactory = new AudiA6CarsFactory();
// 实例化生产奥迪A8的工厂
CarFactory audiA8CarFactory = new AudiA8CarsFactory();
System.out.println("===========顾客A买奥迪A6===========");
// 顾客A想买一辆奥迪A6,那么工厂需要生产奥迪A6
Car myCarA6 = audiA6CarFactory.manufactureCar();
System.out.println("奥迪A6被造好,并且出厂了。");
// 顾客A得到了他想要的汽车
System.out.println("我终于买了"+myCarA6+"。真是太好了!");
System.out.println("===========顾客B买奥迪A8===========");
// 顾客B想买一辆奥迪A8,那么工厂需要生产奥迪A8
Car myCarA8 = audiA8CarFactory.manufactureCar();
System.out.println("奥迪A8被造好,并且出厂了。");
// 顾客B得到了他想要的汽车
System.out.println("我终于买了"+myCarA8+"。真是太好了!");
}
}
操作結果:
===========顾客A买奥迪A6===========
奥迪A6被造好,并且出厂了。
我终于买了一辆奥迪A6。真是太好了!
===========顾客B买奥迪A8===========
奥迪A8被造好,并且出厂了。
我终于买了一辆奥迪A8。真是太好了!
例 6の単純なファクトリ パターンを比較すると、元のファクトリ クラス CarFactory が抽象クラス (インターフェイス) に変更され、2 つの新しい具象ファクトリ クラス (ファクトリ インターフェイスを実装) が追加されて、それぞれ 2 つの異なる製品が作成されていることがわかります。
これを行うことでどのようなメリットがあるのでしょうか?
1. 「オープン-クローズ」原則を満たす:
1) 一汽フォルクスワーゲンが 3 番目のモデルであるアウディ A10 の生産を計画していると想像してください。
例 6の単純なファクトリ パターンを使用する場合、ファクトリ クラス CarFactory を変更して、新しい車のモデルの作成ロジックを追加する必要があります。既存のコードのこの変更は、既存の安定したシステムに多くの不確実性をもたらす可能性があります。エラーとリスク。
ファクトリ メソッド パターンを使用する場合、既存のクラスを変更する必要はなく、特定のプロダクト クラスと特定のファクトリ クラスを追加するだけで済みます。既存システムの安定性を変えることなく拡張が容易です。
2) また、ファクトリメソッドパターンでは静的ファクトリメソッドが使用されなくなりました(通常のメソッドに変更)。これにより、継承の階層構造に基づいたファクトリクラスの拡張が容易になります。
例:アウディ A6 も赤と黒などのモデルカテゴリーに分かれており、アウディ A6 のこれら 2 つの色の生産プロセスも大きく異なる場合、異なる工場で生産する必要があります。次に、 AudiA6CarsFactory の 2 つのサブクラス、 AudiA6RedCarsFactory および AudiA6BlackCarsFactory を作成して、さまざまなレベルの自動車製品の生産を低リスクで便利に拡張できます。
2.「高凝集性と低結合性」の原則を満たします。
上記 1 の 1) と 2) を組み合わせると、同レベルの製品の水平方向の拡大と、製品階層の垂直方向の拡大が起こることがわかります。これらはすべて、工場での製品作成の複雑さを増大させます。
単純なファクトリ パターンを採用すると、ファクトリ クラスはさまざまな製品の複雑な作成プロセスを 1 つに統合するユニバーサル クラスとなり、ソフトウェア システムにおける「高結合性と低結合性」の原則に違反します。その過程では、非常に困難で危険に感じるでしょう。
ファクトリーメソッドパターンを使用すると、さまざまな製品を作成する責任が分離され、各工場が 1 つの製品の作成に集中できるようになり、「高い結合性と低い結合性」の原則が満たされ、製品の維持と拡張が可能になります。システムをより効率的に、簡単かつ安全に。