「デザインパターン」ファクトリーパターン

       オブジェクト指向プログラミングでは、オブジェクト インスタンスを作成する最も一般的な方法は、new 演算子を使用してオブジェクト インスタンスを構築することですが、場合によっては、new 演算子がオブジェクトを直接生成すると問題が発生することがあります。たとえば、オブジェクトの作成には一連の手順が必要です。オブジェクトの初期位置を計算または取得したり、生成するサブオブジェクト インスタンスを選択したり、生成前にいくつかの補助オブジェクトを生成する必要がある場合があります。このような場合、新しいオブジェクトの作成は、より大型の機械のギア トランスミッションのような単なる操作ではなく、「プロセス」となります。

       上記の状況に対応して、オブジェクト サンプルを構築する詳細や複雑なプロセスを気にせずに、オブジェクト インスタンスを簡単かつ便利に構築するにはどうすればよいでしょうか? 解決策は、ファクトリ クラスを使用してオブジェクトを作成することです。

1. ファクトリーモードとは何ですか?

ファクトリ パターンは、オブジェクト作成の特定のプロセスを保護および分離して、より高い柔軟性を実現します。ファクトリ パターンは、次の 3 つのカテゴリに分類できます。

  • シンプルファクトリーパターン(シンプルファクトリー)
  • ファクトリメソッドパターン
  • 抽象ファクトリー パターン (抽象ファクトリー)

これら 3 つのモードは、上から下に向かって徐々に抽象的かつ一般的になります。デザイン パターン』という本では、ファクトリ パターンをファクトリ メソッド パターンと抽象ファクトリ パターンの 2 つのカテゴリに分類しています。単純なファクトリ パターンはファクトリ メソッド パターンの特殊なケースと考えてください。この 2 つは同じカテゴリに分類されます。まず、次のケースからファクトリー モデルについて予備的に理解しましょう。 

(1) 工場のない時代では、顧客が BMW 車を必要とする場合、顧客は BMW 車を作成して使用する必要があります。

(2) 単純な工場モデル: その後、工場が登場し、ユーザーは BMW 車を作る必要がなくなり、工場がそれを作りました。たとえば、320i シリーズの車が必要な場合、工場はこのシリーズの車を製造します。

(3) 工場方式モデル: 顧客を満足させるために、320i、523i などの BMW 車シリーズがますます増えています。1 つの工場ですべての BMW シリーズを生産することはできないため、複数の特定の工場が分離され、それぞれの工場で生産されます。シリーズ、つまり特定のファクトリ クラスは特定の製品のみを作成できます。しかし、BMW の工場は依然として抽象的なものであり、車を生産するには特定の工場を指定する必要があります。

(4) 抽象的な工場モデル: 顧客の要求がますます高くなるにつれて、BMW 車にはエアコンを装備する必要があるため、この工場は BMW 車と必要なエアコンの生産を開始しました。最終的に、顧客は BMW の販売員に「523i エアコン付きの車が欲しい」と言うだけで済み、販売員は直接 523i エアコン付きの車を彼に渡します。523i エアコン付き BMW を自分で作成する代わりに。

以下に、いくつかの異なるファクトリーモードについて詳しく説明します。

2. 簡易ファクトリーモード

シンプルなファクトリ パターンの中核は、オブジェクトを作成するためのインターフェイスを定義することであり、これにより、オブジェクトの作成が独自のビジネス ロジックから分離され、システムの結合が軽減され、2 つの変更が比較的簡単になります。変更する必要があるのはファクトリ クラスのみです。

ファクトリを使用しない場合、ユーザーは自分で BMW 車を作成することになります。具体的な UML ダイアグラムとコードは次のとおりです。

public class BMW320 {
	public BMW320(){
		System.out.println("制造-->BMW320");
	}
}
 
public class BMW523 {
	public BMW523(){
		System.out.println("制造-->BMW523");
	}
}
 
public class Customer {
	public static void main(String[] args) {
		BMW320 bmw320 = new BMW320();
		BMW523 bmw523 = new BMW523();
	}
}

ユーザーは、顧客と車が密接に結びつくように、車の作り方を知る必要がありますが、その結びつきを減らすために、BMW の製造に関するすべての操作詳細を工場に組み込んだシンプルな工場モデルが登場しました。お客様は工場のメソッドを直接使用し、作成の詳細を知らなくても、希望する BMW モデルを渡すだけでメソッドを作成できます。

2.1. 単純なファクトリパターンのUML図

  • 工場の役割: 製品を作成するために使用されるこのモデルのコアには、特定のビジネス ロジックと判断ロジックが含まれています
  • 抽象製品の役割: これは通常、特定の製品または実装されたインターフェイスによって継承される親クラスです。   
  • 特定の製品ロール: ファクトリ クラスによって作成されたオブジェクトは、このロールのインスタンスです。Javaの具象クラスによって実装されます。

2.2. コードの実装

製品カテゴリ:

abstract class BMW {
	public BMW(){}
}
 
public class BMW320 extends BMW {
	public BMW320() {
		System.out.println("制造-->BMW320");
	}
}
public class BMW523 extends BMW{
	public BMW523(){
		System.out.println("制造-->BMW523");
	}
}

ファクトリクラス:

public class Factory {
	public BMW createBMW(int type) {
		switch (type) {
		
		case 320:
			return new BMW320();
 
		case 523:
			return new BMW523();
 
		default:
			break;
		}
		return null;
	}
}

ユーザークラス:

public class Customer {
	public static void main(String[] args) {
		Factory factory = new Factory();
		BMW bmw320 = factory.createBMW(320);
		BMW bmw523 = factory.createBMW(523);
	}
}

2.3. 簡易ファクトリーモデルの長所と短所

シンプル ファクトリ パターンは、オブジェクト作成のための特殊なファクトリ クラスを提供し、オブジェクトの作成と使用の責任の分離を実現します。クライアントは、作成された特定のプロダクト クラスのクラス名と作成プロセスを知る必要はなく、知っておくだけで済みます。特定の製品クラスに対応するクラス名 パラメータのみで十分 設定ファイルを導入することで、クライアントコードを変更することなく、新しい特定の製品カテゴリを置き換えたり追加したりすることができ、システムの柔軟性がある程度向上します。

ただし、「開閉原則」に準拠していないため、新しい製品が追加されるたびにファクトリ クラスを変更する必要があるという欠点があります。製品の種類が多いと、ファクトリのロジックが複雑になりすぎてシステムの拡張や保守が困難になるだけでなく、製品作成のロジックがすべてファクトリクラスに集約されるため、一度正常に動作しなくなるとシステム全体に影響を及ぼします。

単純なファクトリー・パターンの問題を解決するために、ファクトリー・メソッド・パターンが登場しました。

3. ファクトリメソッドパターン

ファクトリ メソッド パターンはファクトリを抽象化し、オブジェクトを作成するためのインターフェイスを定義します。新しい製品を追加するたびに、その製品と、対応する特定の実装ファクトリ クラスを追加するだけで済みます。特定のファクトリ クラスは、どの製品をインスタンス化するかを決定し、オブジェクトの作成とサブクラスへのインスタンス化を遅らせます。工場の設計は「開閉原則」に準拠しているため、拡張時に元のコードを変更する必要はありません。これを使用する際に必要なのは、製品に対応する特定の工場を知り、特定の作成プロセスに注意を払うことだけであり、特定の製品クラスのクラス名を知る必要さえありません。実際にどの製品を作るかはすでに決まっています。

ただし、欠点は、製品を追加するたびに、特定の製品クラスと実装ファクトリー クラスを追加する必要があることです。これにより、システム内のクラスの数が 2 倍になり、システムの複雑さがある程度増加し、システムのコストも増加します。システム内の特定のクラスの数。

3.1. ファクトリメソッドのUML構造図は以下の通り

抽象ファクトリ AbstractFactory: ファクトリ メソッド パターンのコアは、特定のファクトリ ロールが実装する必要があるインターフェイス、または継承する必要がある親クラスです。Java では、抽象クラスまたはインターフェイスによって実装されます。 
特定のファクトリ ファクトリ: 特定のビジネス ロジックに関連するコードを含む、特定の製品を作成するためにアプリケーションによって呼び出されるオブジェクト 抽象
製品: 特定の製品によって継承される親クラスまたは実装されたインターフェイス Java では、通常、抽象クラスまたはインターフェイスが存在します。を実装します。 
特定の製品 Product: 特定のファクトリ ロールによって作成されたオブジェクトは、このロールのインスタンスです。

3.2. コードの実装

製品カテゴリ:

abstract class BMW {
	public BMW(){}
}
public class BMW320 extends BMW {
	public BMW320() {
		System.out.println("制造-->BMW320");
	}
}
public class BMW523 extends BMW{
	public BMW523(){
		System.out.println("制造-->BMW523");
	}
}

ファクトリクラス: 

interface FactoryBMW {
	BMW createBMW();
}
 
public class FactoryBMW320 implements FactoryBMW{
 
	@Override
	public BMW320 createBMW() {
		return new BMW320();
	}
 
}
public class FactoryBMW523 implements FactoryBMW {
	@Override
	public BMW523 createBMW() {
		return new BMW523();
	}
}

顧客クラス:

public class Customer {
	public static void main(String[] args) {
		FactoryBMW320 factoryBMW320 = new FactoryBMW320();
		BMW320 bmw320 = factoryBMW320.createBMW();
 
		FactoryBMW523 factoryBMW523 = new FactoryBMW523();
		BMW523 bmw523 = factoryBMW523.createBMW();
	}
}

4. 抽象的なファクトリーパターン

ファクトリ メソッド パターンでは、ファクトリを使用して製品を作成し、特定のファクトリが特定の製品に対応します。ただし、場合によっては、単一のオブジェクトではなく複数の製品オブジェクトを提供するファクトリが必要になります。この場合、次のようにする必要があります。抽象的なファクトリーモデル。

抽象ファクトリー パターンを導入する前に、まず 2 つの概念を明確にします。

  • 製品レベル構造: 製品レベル構造は、製品の継承構造を指します。たとえば、エアコンの抽象クラスには、ハイアール エアコン、グリー エアコン、美的エアコンなどの一連のサブクラスがあります。次に、このエアコン抽象クラスとそのサブクラスは、製品階層を確立します。
  • 製品ファミリー: 製品ファミリーとは、同じ工場で生産され、異なる製品階層構造に位置する製品のグループを指します。たとえば、ハイアール工場はハイアール エアコンとハイアール冷蔵庫を生産しているため、ハイアール エアコンは空調製品ファミリーに含まれます。
     

製品レベル構造と製品ファミリー構造の概略図は次のとおりです。

4.1. 抽象ファクトリーパターンとは何ですか?

抽象ファクトリー パターンは主に、関連オブジェクトのファミリーを作成するために使用されます。製品ファミリが連携して動作するように設計する必要がある場合、抽象ファクトリ パターンにより、クライアントが常に同じ製品ファミリ内のオブジェクトのみを使用することが保証され、特定のクラスの生成を分離することで、クライアントは特定のクラスを明示的に指定する必要がなくなります。すべての具象ファクトリは、抽象ファクトリで定義されたパブリック インターフェイスを実装するため、具象ファクトリのインスタンスを変更するだけで、ソフトウェア システム全体の動作をある程度変更できます。

ただし、このモデルの欠点は、新しい動作を追加するのがより面倒であることであり、新しい製品ファミリー オブジェクトを追加する必要がある場合、インターフェイスとそのすべてのサブクラスを変更する必要があり、必然的に多くのトラブルが発生します。

4.2. UML 構造図

Abstract Factory AbstractFactory: 製品を生産するための一連のメソッドを含むインターフェイスを定義します。すべての具象ファクトリはこのインターフェイスを実装する必要があります。
ConcreteFactory: さまざまな製品ファミリーの生成に使用されます。製品を作成するには、ユーザーは、製品オブジェクトをインスタンス化することなく、ファクトリの 1 つを使用してそれを取得するだけで済みます。
抽象製品: これは製品ファミリーであり、特定の各工場が製品の完全なセットを生産できます。
特定の製品製品

4.3. コードの実装

抽象的なファクトリー パターンを通じて、次の効果を実現できます。たとえば、BMW 320 シリーズではエアコン モデル A とエンジン モデル A が使用され、BMW 230 シリーズではエアコン モデル B とエンジン モデル B が使用されます。 320 シリーズの場合、アクセサリのモデルを指定する必要はありません。車種に応じて、対応するアクセサリ モデル A が自動的に生成されます。

言い換えれば、各抽象製品に複数の具体的なサブクラスがある場合 (エアコンには 2 つのモデル A と B があり、エンジンにも 2 つのモデル A と B があります)、ファクトリの役割はどのサブクラスをインスタンス化するかをどのようにして知るのでしょうか? 毛織物? 抽象ファクトリ パターンは、2 つの特定のファクトリ ロール (BMW 320 シリーズ ファクトリと BMW 230 シリーズ ファクトリ) を提供し、これら 2 つの特定の製品ロールにそれぞれ対応します。各特定のファクトリ ロールは、特定の製品ロールのインスタンス化のみを担当します。各特定のファクトリは、クラスは、抽象製品の特定のサブクラスのインスタンスを作成することのみを担当します。

製品カテゴリ:

//发动机以及型号  
public interface Engine {}  
 
public class EngineA implements Engine{  
    public EngineA(){  
        System.out.println("制造-->EngineA");  
    }  
}  
public class EngineB implements Engine{  
    public EngineB(){  
        System.out.println("制造-->EngineB");  
    }  
}  
 
 
//空调以及型号  
public interface Aircondition {} 
 
public class AirconditionA implements Aircondition{  
    public AirconditionA(){  
        System.out.println("制造-->AirconditionA");  
    }  
}  
public class AirconditionB implements Aircondition{  
    public AirconditionB(){  
        System.out.println("制造-->AirconditionB");  
    }  
} 

ファクトリクラスを作成します。

//创建工厂的接口  
public interface AbstractFactory {  
    //制造发动机
    public Engine createEngine();
    //制造空调 
    public Aircondition createAircondition(); 
}  
 
//为宝马320系列生产配件  
public class FactoryBMW320 implements AbstractFactory{     
    @Override  
    public Engine createEngine() {    
        return new EngineA();  
    }  
    @Override  
    public Aircondition createAircondition() {  
        return new AirconditionA();  
    }  
}  
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {  
     @Override  
    public Engine createEngine() {    
        return new EngineB();  
    }  
    @Override  
    public Aircondition createAircondition() {  
        return new AirconditionB();  
    }  
} 

クライアント:

public class Customer {  
    public static void main(String[] args){  
        //生产宝马320系列配件
        FactoryBMW320 factoryBMW320 = new FactoryBMW320();  
        factoryBMW320.createEngine();
        factoryBMW320.createAircondition();
          
        //生产宝马523系列配件  
        FactoryBMW523 factoryBMW523 = new FactoryBMW523();  
        factoryBMW523.createEngine();
        factoryBMW523.createAircondition();
    }  
}

5. 純正モデルの概要

ファクトリ メソッド パターンと抽象ファクトリ パターンの違いは次のとおりです。

(1) ファクトリ メソッドは抽象プロダクト クラスと抽象ファクトリ クラスを 1 つだけ持ちますが、複数の具象プロダクト クラスと具象ファクトリ クラスを派生でき、各具体ファクトリ クラスは具象プロダクト クラスのインスタンスを 1 つだけ作成できます。

(2) 抽象ファクトリ パターンは複数の抽象プロダクト クラス (プロダクト ファミリ) と 1 つの抽象ファクトリ クラスを持ち、各抽象プロダクト クラスは複数の具体的なプロダクト クラスを派生でき、抽象ファクトリ クラスも複数の具体的なファクトリ クラスを派生できます。具象ファクトリ クラスは具象製品クラスの複数のインスタンスを作成できます
 

おすすめ

転載: blog.csdn.net/m0_50370837/article/details/126245282