23のデザインパターン - 工場パターン

工場パターン(よく使われる)

  • 工場モード導入:
    • オブジェクトを作成するための最適な方法を提供します。オブジェクトを作成するときに作成ロジックをクライアントに公開せず、共通のインターフェイスを使用して新しく作成されたオブジェクトをポイントします。
  • 例⼦:
    • この工場はコンピュータを生産しており、ブランド A に加えて、ブランド B、C、および D のコンピュータも生産できます。
    • ビジネスの発展において、支払いは非常に一般的であり、統一された注文と支払いのインターフェースがあり、特定の支払いの実装はWeChat、Alipay、銀行カードなどです。
  • ファクトリ モードには3 つの異なる実装が あります。
    • 単純なファクトリ モード: 関連する型を渡すことによって対応するクラスを返します。このメソッドは比較的単純であり、スケーラビリティは比較的貧弱です。
    • ファクトリーメソッドモード:実装クラスの対応するメソッドを実装して、対応する戻り値を決定することにより、このメソッドは強力なスケーラビリティを備えています。
    • 抽象工場モード: 上記の 2 つのモードの拡張に基づいており、洗練された製品をサポートします。
  • アプリケーション シナリオ:
    • デカップリング: 責任の分離、複雑なオブジェクトの作成と使用のプロセスの分離
    • コードを再利用してメンテナンス コストを削減します。
      • オブジェクトの作成が複雑で多くの場所で使用する必要がある場合、場所ごとに記述するとコードの繰り返しが多くなり、ビジネス ロジックが変更される場合はあらゆる場所で変更する必要があります。
      • ファクトリ モードを使用して均一に作成する場合は、ファクトリ クラスを変更するだけでコストを削減できます。

ファクトリ パターン - シンプルなファクトリ パターン (最もよく使用される)

  • シンプルファクトリーモード(静的ファクトリー)

    • 静的ファクトリメソッドとも呼ばれ、さまざまなパラメーターに従ってさまざまなクラスのインスタンスを返すことができ、クラスは他のクラスのインスタンスの作成を担当するように特別に定義されています. 作成されたインスタンスには通常、共通の親クラスがあります。
    • ファクトリ メソッドは静的メソッドであるため、クラス名を介して直接呼び出すことができ、単純なパラメーターのみを渡す必要があります。
  • コア組成

    • Factory : 単純なファクトリ パターンのコアであるファクトリ クラス。すべてのインスタンスを作成する内部ロジックの実装を担当します。
    • IProduct : 抽象製品クラス。単純なファクトリ パターンによって作成されたすべてのオブジェクトの親クラスであり、すべてのインスタンスによって共有される共通のインターフェイスを記述します。
    • Product : シンプルファクトリーモードの作成対象となる特定の商品カテゴリ
  • 実装手順

    • 特定の製品クラスによって実装される、製品の抽象メソッドを含む抽象製品クラスを作成します
    • 具体的な製品クラスを作成し、その親クラスを継承し、具体的なメソッドを実装します
    • 製品を生成するための静的メソッドを提供するファクトリ クラスを作成しcreateXXX()、必要な製品の名前を渡すだけです
  • アドバンテージ:

    • オブジェクト自体のビジネス処理からオブジェクトの作成を分離することで、システムの結合を減らすことができ、両方を比較的簡単に変更できます。
  • 欠点:

    • ファクトリクラスの責任は比較的重く、新製品を追加するには、ファクトリクラスの判断ロジックを変更する必要があり、オープンとクローズの原則に反しています。
    • つまり、Open Close Principle は拡張に対してオープンであり、変更に対してクローズされています. プログラムを拡張する必要がある場合、ホットスワップ可能な効果を達成するために元のコードを変更することはできません.
    • システム内のクラスの数が増えるため、システムの複雑さと理解がある程度難しくなり、システムの拡張と保守につながりません。また、単純なオブジェクトの作成にはパターンが使用されません。

単純な (静的) ファクトリ デザイン パターンを簡単に使用してみましょう。

機能説明:

簡単に疑似コードを使用して支払いプロセスをシミュレートしてみましょう。

IProduct 抽象製品インターフェイスの作成 - IPay


/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: IPay抽象统一支付下单接口
 */
public interface IPay {
    
    

    /**
     * 统一下单
     */
    void unifiedOrder();
}

Alipay 決済用の特定の実装クラスを作成 – AliPay

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 支付宝支付具体实现类
 */
public class AliPay implements IPay{
    
    
    @Override
    public void unifiedOrder() {
    
    
        System.out.println("支付宝支付统一下单...");
    }
}

WeChat 支払い用の特定の実装クラスを作成する – WeChatPay


/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 微信支付具体实现类
 */
public class WeChatPay implements IPay{
    
    
    @Override
    public void unifiedOrder() {
    
    
        System.out.println("微信支付统一下单...");
    }
}

シンプルな支払いファクトリ クラス (静的ファクトリ クラス) を作成する – SimplePayFactory


/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 简单支付工厂类(静态工厂类)
 */
public class SimplePayFactory {
    
    

    /**
     * 工厂创建方法:
     * 根据参数返回对应的支付对象
     *
     * @param payType
     * @return
     */
    public static IPay createPay(String payType) {
    
    
        if (payType == null) {
    
    
            return null;
        } else if (payType.equalsIgnoreCase("WECHAT_PAY")) {
    
    
            return new WeChatPay();
        } else if (payType.equalsIgnoreCase("ALI_PAY")) {
    
    
            return new AliPay();
        }
        // 如果需要扩展,可以编写更剁
        return null;
    }
}

シンプルな支払いファクトリーを使用してテストします。

package com.iswhl.EasyFactory;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 简单支付工厂类(静态工厂类)
 */
public class SimplePayFactory {
    
    

    /**
     * 工厂创建方法:
     * 根据参数返回对应的支付对象
     *
     * @param payType
     * @return
     */
    public static IPay createPay(String payType) {
    
    
        if (payType == null) {
    
    
            return null;
        } else if (payType.equalsIgnoreCase("WECHAT_PAY")) {
    
    
            return new WeChatPay();
        } else if (payType.equalsIgnoreCase("ALI_PAY")) {
    
    
            return new AliPay();
        }
        // 如果需要扩展,可以编写更剁
        return null;
    }
}

上記はファクトリ設計パターン - 単純なプロジェクト (静的ファクトリの単純な使用例) です。次に、その欠点と欠点を分析しましょう。

要件:

  • 銀行Aの銀行カード支払いを追加する必要がある場合は、別の判断を追加する、銀行Aの支払いロジックを追加するSimplePayFactoryなど、クラスに応答判断ロジックを追加する必要がありますif
  • ifそして、銀行Bの別の銀行カード支払いが必要な場合は、銀行Bの支払いを判断して追加する別のロジックを追加し、それを順番に追加する必要があります...
  • 次に、これはオープン クローズの原則 (オープン クローズの原則) に違反し、ファクトリ クラス (拡張用にオープン、変更用にクローズ、プログラムを拡張する必要がある場合、元のコードを変更してホットスワップ可能にすることはできません) が従います。 )、機能を拡張するたびに新しいロジックを追加する必要があり、ファクトリクラスを変更する必要があり、実際の複雑なビジネスである場合、これはコストの増加につながります。

単純なファクトリ パターンのこの欠点をファクトリ メソッド パターンがどのように解決するかを見てみましょう。

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

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

    • ファクトリーモードとも呼ばれ、単純なファクトリーモードをさらに抽象化したもので、システムが元のコードを変更せずに新製品を導入できる、つまり開閉の原則を満たしているという利点があります。

    • 製品の作成を担当するパブリック インターフェイスはファクトリ クラスによって定義され、作成される型はサブクラスによって決定されます。

    • 単純なファクトリと比較して、この方法はスケーラビリティ再利用性が高く、コードの可読性も向上します

    • クラスのインスタンス化 (特定の製品の作成) をファクトリ クラスのサブクラス (具体的なファクトリ) に遅らせる。つまり、サブクラスがどのクラスをインスタンス化するかを決定します。

  • コア組成

    • IProduct : すべてのインスタンスで共有される共通のインターフェースを記述する抽象的な製品インターフェース
    • Product : 具体的な製品クラス、抽象製品クラスのインターフェースを実装し、ファクトリ クラスにオブジェクトを作成します.複数ある場合は、複数定義する必要があります.
    • IFactory : 特定のファクトリのパブリック インターフェイスを記述する抽象ファクトリ インターフェイス
    • ファクトリ: 具体的なファクトリ クラス、製品クラス オブジェクトの作成を実現し、抽象ファクトリ クラスのインターフェイスを実現します。複数ある場合は、複数定義する必要があります。

ここに画像の説明を挿入

ファクトリ メソッド パターンを実装するには、元の単純なファクトリ パターンに基づいて改良を加えるだけでよく、以前に作成したIPay抽象製品インターフェイスとAliPay WeChatPay2 つの具象製品クラスを変更する必要はありません。

まず、IPayFactory抽象ファクトリ インターフェイスを作成します。

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 抽象⼯⼚接口
 */
public interface IPayFactory {
    
    
    IPay getPay();
}

次に、2 つの具体的なファクトリ クラスを作成しAliPayFactoryますWeChatFactory

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 具体工厂类 AliPayFactory
 */
public class AliPayFactory implements IPayFactory{
    
    
    @Override
    public IPay getPay() {
    
    
        return new AliPay();
    }
}

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 具体工厂类 WeChatFactory
 */
public class WeChatFactory implements IPayFactory{
    
    
    @Override
    public IPay getPay() {
    
    
        return new WeChatPay();
    }
}

テストを実行します。

@Test
public void testMethodPayFactory(){
    
    
    AliPayFactory aliPayFactory = new AliPayFactory();
    IPay ali_pay = aliPayFactory.getPay();
    ali_pay.unifiedOrder();// 输出:支付宝支付统一下单...
    WeChatFactory weChatFactory = new WeChatFactory();
    IPay wechat_pay = weChatFactory.getPay();
    wechat_pay.unifiedOrder();// 输出:微信支付统一下单...
}
  • ファクトリ メソッド パターンの利点:

    • オープンとクローズの原則に沿って、製品カテゴリを追加するには、他の特定の製品カテゴリと特定の工場カテゴリを実装するだけで済みます。

    • 単一責任の原則に沿って、各工場は対応する製品の生産に対してのみ責任を負います。

    • ユーザーは、製品の抽象クラスを知るだけでよく、他の実装クラスを気にする必要はなく、ディミターの法則、依存性逆転の原則、およびライム交換の原則を満たします。

      • ディミテルの法則: 最小知識の原則。エンティティは他のエンティティとのやり取りをできるだけ少なくする必要があります。
      • 依存性逆転の原則: インターフェイス プログラミングでは、具象ではなく抽象化に依存します。
      • Liao 置換原則: 一般に LSP として知られています。ここでは、任意の基本クラスを表示でき、サブクラスを表示する必要があり、抽象化を実現するための特定の手順を指定します。
  • ファクトリ メソッド パターンの欠点:

    • 製品を追加するには、対応する特定の工場カテゴリと特定の製品カテゴリを実装する必要があります。
    • 各製品には、対応する特定の工場と特定の製品カテゴリが必要です。

ファクトリ パターン - 抽象ファクトリ メソッド パターン

抽象ファクトリ メソッド パターンは、シンプル ファクトリ パターンとファクトリ メソッド パターンの統合およびアップグレード バージョンです

  • ファクトリ パターンには 3 つの異なる実装があります。

    • 単純なファクトリ モード: 関連する型を渡して対応するクラスを返します。このメソッドは比較的単純で、スケーラビリティは比較的貧弱です。

    • ファクトリーメソッドモード:実装クラスの対応するメソッドを実装して、対応する戻り値を決定することにより、このメソッドは強力なスケーラビリティを備えています。

    • 抽象ファクトリーモード: 上記2つのモードの拡張に基づき, ファクトリーメソッドモードのアップグレード版. 作成する製品が複数の製品ラインを持つ場合, 抽象ファクトリーモードを使用することをお勧めします.

    • 抽象ファクトリ パターンは、Spring で最も広く使用されているデザイン パターンです。

  • バックグラウンド:

    • ファクトリ メソッド モードではファクトリ階層構造が導入され、シンプル ファクトリ モードでのファクトリ クラスの責任の重さの問題が解決されます。
    • ただし、ファクトリ メソッド パターンでは、各ファクトリは 1 種類の具象クラスのオブジェクトのみを作成し、その後の開発で多数のファクトリ クラスが生成される可能性があるため、関連するいくつかの具象クラスは、 A ファクトリによって「具象クラス ファミリに結合されます。統一された生産は、一連の関連製品オブジェクトを強調します! ! !
  • 実装手順:

    • 1. IPay (支払い) と IRefund (返金) の 2 つのインターフェイスを定義します。
    • 2. 特定の有料商品と特定の払い戻し商品を作成する
    • 3. 2 つのメソッド createPay/createRefund を使用して、抽象ファクトリ IOrderFactory インターフェイスを作成します。
    • 4. Alipay 製品ファミリ AliOderFactory を作成し、OrderFactory 抽象ファクトリを実装します。
    • 5. WeChat 決済製品ファミリである WechatOderFactory を作成し、OrderFactory の抽象ファクトリを実現する
    • 6. スーパー ファクトリ クリエータ FactoryProducer を定義し、パラメータを渡して対応するファクトリを取得します。
      ここに画像の説明を挿入

次に、抽象ファクトリ メソッド パターンを使用する手順に従います。

1. IPay (支払い) と IRefund (返金) の 2 つのインターフェイスを定義します。

package com.iswhl.FactoryMethod;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: IPay抽象统一支付下单接口
 */
public interface IPay {
    
    

    /**
     * 统一下单
     */
    void unifiedOrder();
}
package com.iswhl.FactoryMethod;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 退款抽象接口
 */
public interface IReFund {
    
    

    /**
     * 退款
     */
    void refund();
}

2. 特定の Pay 製品と特定の Refund 製品を作成します。

AliPay/WeChatPay : Alipay決済とWeChat決済

package com.iswhl.FactoryMethod;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 具体工厂类 AliPayFactory
 */
public class AliPayFactory implements IPayFactory{
    
    
    @Override
    public IPay getPay() {
    
    
        return new AliPay();
    }
}

package com.iswhl.FactoryMethod;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 微信支付具体实现类
 */
public class WeChatPay implements IPay {
    
    
    @Override
    public void unifiedOrder() {
    
    
        System.out.println("微信支付统一下单...");
    }
}

AliRefund/WeChatFund : Alipay の払い戻しと WeChat の払い戻し

package com.iswhl.FactoryMethod;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description:
 */
public class AliRefund implements IReFund {
    
    
    @Override
    public void refund() {
    
    
        System.out.println("支付宝退款...");
    }
}

package com.iswhl.FactoryMethod;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description:
 */
public class WeChatRefund implements IReFund {
    
    
    @Override
    public void refund() {
    
    
        System.out.println("微信支付退款...");
    }
}

3. 2 つのメソッド createPay/createRefund を使用して抽象ファクトリ IOrderFactory インターフェイスを作成します。

package com.iswhl.FactoryMethod;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 订单抽象工厂,一个超级工厂可以创建其他工厂(又被称为其他工厂的工厂)
 */
public interface IOrderFactory {
    
    

    IPay createPay();

    IReFund createRefund();
}

4. Alipay 製品ファミリ AliOderFactory を作成し、OrderFactory 抽象ファクトリを実装します。

package com.iswhl.FactoryMethod;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description:
 */
public class AliOrderFactory implements IOrderFactory {
    
    
    @Override
    public IPay createPay() {
    
    
        return new AliPay();
    }

    @Override
    public IReFund createRefund() {
    
    
        return new AliRefund();
    }
}

5. WeChat 決済製品ファミリである WechatOderFactory を作成し、OrderFactory の抽象ファクトリを実現する

package com.iswhl.FactoryMethod;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description:
 */
public class WeChatOrderFactory implements IOrderFactory {
    
    
    @Override
    public IPay createPay() {
    
    
        return new WeChatPay();
    }

    @Override
    public IReFund createRefund() {
    
    
        return new WeChatRefund();
    }
}

6. スーパー ファクトリ クリエータ FactoryProducer を定義し、パラメータを渡して対応するファクトリを取得します。

package com.iswhl.FactoryMethod;

/**
 * @Auther: whl
 * @Date: 2022/8/08/10:00
 * @Description: 工厂创造器
 */
public class FactoryProducer {
    
    

    public static IOrderFactory getFactory(String type){
    
    
        if (type.equalsIgnoreCase("WECHAT")){
    
    
            return new WeChatOrderFactory();
        }else if (type.equalsIgnoreCase("ALI")){
    
    
            return new AliOrderFactory();
        }
        return null;
    }
}

最後に、テストしましょう:

package com.iswhl.FactoryMethod;

public class test {
    
    
    public static void main(String[] args) {
    
    
        IOrderFactory wechatPayFactory = FactoryProducer.getFactory("WECHAT");
        wechatPayFactory.createPay().unifiedOrder();
        wechatPayFactory.createRefund().refund();
        IOrderFactory aliPayFactory = FactoryProducer.getFactory("ALI");
        aliPayFactory.createPay().unifiedOrder();
        aliPayFactory.createRefund().refund();
    }
}

結果は次のとおりです。

微信支付统一下单...
微信支付退款...
支付宝支付 统一下单接口...
支付宝退款...
  • ファクトリ メソッド パターンと抽象ファクトリ メソッド パターン

    • 抽象ファクトリ パターン内の各具象ファクトリ クラスが 1 つの製品オブジェクトのみを作成する場合、抽象ファクトリ パターンはファクトリ メソッド パターンに退化します。
  • アドバンテージ

    • 製品ファミリ内の複数のオブジェクトが連携して動作するように設計されている場合、消費者は常に同じ製品ファミリのオブジェクトのみを使用することが保証されます
    • 製品レベル構造は拡張が容易で、別の製品レベルを追加する必要がある場合は、銀行支払いや払い戻しの追加など、新しい工場カテゴリと製品カテゴリを追加するだけで済みます
  • 欠点

    • 製品ファミリを拡張することは困難です. 特定の製品をシリーズに追加するには、抽象ファクトリと抽象製品のコードを変更する必要があり、開閉の原則に準拠していません.
    • システムの抽象化と理解の難しさの増加

おすすめ

転載: blog.csdn.net/Ghoul___/article/details/126224996