ファクトリメソッドファクトリメソッドパターン(Javaコードの実装)-作成パターン

私が23のデザインパターンについて書いた記事では、序文は基本的に同じです。読者は第2章から読み始めることができます。この記事は工厂方法模式(Factory Method Pattern)、作成パターンの詳細な説明についてです。

1はじめに

著書「デザインパターン-再利用可能なオブジェクト指向ソフトウェアの要素」(中国語訳:デザインパターン-再利用可能なオブジェクト指向ソフトウェアの基礎)によると、4人の著者はデザインパターンを次のように3つのカテゴリに分類しています。

1.作成パターン
これらのデザインパターンは、新しい演算子を使用してオブジェクトを直接インスタンス化する代わりに、オブジェクトの作成中に作成ロジックを非表示にする方法を提供します。これにより、プログラムは、特定のインスタンスに対して作成する必要のあるオブジェクトをより柔軟に決定できます。

  • シングルトンパターン
  • 抽象ファクトリパターン
  • 工厂方法模式(Factory Method Pattern)
  • ビルダーパターン
  • プロトタイプパターン

2.構造パターン
これらのデザインパターンは、クラスとオブジェクトの構成に焦点を当てています。継承の概念は、インターフェースを構成し、複合オブジェクトが新しい機能を取得する方法を定義するために使用されます。

  • アダプターパターン
  • ブリッジパターン
  • 複合パターン
  • デコレータパターン
  • ファサードパターン
  • フライウェイトパターン
  • プロキシパターン

3.動作パターン
これらのデザインパターンは、特にオブジェクト間の通信に関係しています。

  • 責任の連鎖パターン
  • コマンドパターン
  • インタープリターパターン
  • イテレータパターン
  • メディエーターパターン
  • Mementoパターン
  • オブザーバーパターン
  • 状態パターン
  • 戦略パターン
  • テンプレートパターン
  • ビジターパターン

この記事は、作成モードで工厂方法模式(Factory Method Pattern)の詳細な説明についてです。

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

2.1。意図

オブジェクトを作成するためのインターフェースを定義し、サブクラスにインスタンス化するクラスを決定させます。ファクトリメソッドは、クラスのサブクラスへのインスタンス化を遅らせます。

2.2UMLクラス図

ファクトリモードでは、オブジェクトを作成するときに作成ロジックをコンシューマーに公開せず、次のように共通のインターフェイス(下図のTeaFactory)を使用して新しく作成されたオブジェクトをポイントします(現在人気のあるミルクティーを例):
ここに画像の説明を挿入

2.3.Javaコード固有の実装

2.3.1パッケージ構造は次のとおりです。

ここに画像の説明を挿入

2.3.2ティーパッケージ

public interface Tea {
    
    
    void make();
}
public class BlackTea implements Tea {
    
    


    @Override
    public void make() {
    
    
        System.out.println("make the black tea!");
    }
}
public class GreenTea implements Tea {
    
    
    @Override
    public void make() {
    
    
        System.out.println("make the green tea!");
    }
}
public class MilkTea implements Tea {
    
    
    @Override
    public void make() {
    
    
        System.out.println("make the milk tea!");
    }
}

2.3.3ファクトリーパッケージ

/**
 * @Author: YuShiwen
 * @Date: 2022/2/3 10:43 PM
 * @Version: 1.0
 */
public class TeaFactory {
    
    
    public Tea getTea(String tea) {
    
    
        if ("blackTea".equalsIgnoreCase(tea)) {
    
    
            return new BlackTea();
        } else if ("greenTea".equalsIgnoreCase(tea)) {
    
    
            return new GreenTea();
        } else if ("milkTea".equalsIgnoreCase(tea)) {
    
    
            return new MilkTea();
        } else {
    
    
            throw new RuntimeException("其他茶品暂不支持!");
        }
    }
}

2.3.4メインパッケージ

public class CustomerDemo {
    
    
    public static void main(String[] args) {
    
    
        new TeaFactory().getTea("milktea").make();
        new TeaFactory().getTea("blacktea").make();
    }
}

2.3.5実行結果

ここに画像の説明を挿入

2.4.長所と短所

利点:
1。呼び出し元がオブジェクトを作成したい場合、呼び出し元はその名前を知っているだけで済みます。
2.高いスケーラビリティ。製品を追加する場合は、ファクトリクラスを拡張するだけで済みます。
3.シールド製品の特定の実装はシールドされており、発信者は製品のインターフェースのみを気にします。

短所:
製品を追加するたびに、特定のクラスとオブジェクトの実装ファクトリを追加する必要があります。これにより、システム内のクラスの数が2倍になり、システムの複雑さがある程度増加し、特定のクラスのクラスも増加します。システム。依存します。

推奨事項:
クラス作成パターンとして、複雑なオブジェクトを生成する必要がある場合は常に、ファクトリメソッドパターンを使用できます。注意すべき点の1つは、複雑なオブジェクトはファクトリパターンの使用に適していますが、単純なオブジェクト、特に新規でのみ作成できるオブジェクトは、ファクトリパターンを使用する必要がないことです。ファクトリパターンを使用する場合は、ファクトリクラスを導入する必要があります。これにより、システムが複雑になります。

2.5ソースコードでのアプリケーション

2.5.1Integer.valueOf()メソッド

  • 整数整数を作成するための静的メソッドvalueOf()を提供します。では、このメソッドと新しいInteger(3)を直接書き込むことの違いは何ですか?valueOf()メソッドを観察します。
    その利点は、valueOf()が内部でnewを使用して新しいIntegerインスタンスを作成できることですが、キャッシュされたIntegerインスタンスを直接返すこともできます。
  • 整数のデフォルトは[-128、127]のキャッシュ範囲です。ソースコードを見るとわかりました。lowの下限は、最初に修正されたfinal int low=-128です。finalintは設定されていますが、最初は割り当てられていないため、javaのパラメーターを設定することでランタイムパラメーターを構成できます。
    java -D java.lang.Integer.IntegerCache.high=1024 TestAutoBoxCache
    ここに画像の説明を挿入

呼び出し元が整数作成の詳細を知っている必要はありません。
ファクトリメソッドは、製品の作成の詳細を隠すことができ、必ずしも毎回製品を作成する必要はありません。キャッシュされた製品を返すことができるため、速度が向上し、メモリ消費量が削減されます。

2.5.2List.of()メソッド

  • List.of()は、Java9によって提供されるメソッドです。この静的ファクトリメソッドは、変数パラメーターを受け入れ、Listインターフェイスを返します。Arrays.asList()メソッドと比較すると、元の配列の変更は、Arrays.asListによって生成されたリストには影響しますが、List.ofによって生成されたリストには影響しません。
  • 呼び出し元が取得する製品は常にリストインターフェイスであり、実際のタイプは関係ありません。List製品の実際のタイプがjava.util.ImmutableCollections$ListNであることを呼び出し元が知っている場合でも、静的ファクトリメソッドList.of()はListを返すことが保証されているため、サブクラスにキャストしないでください。 java.util.ArrayListを返すように変更します。これがリスコフの置換原則です。インターフェースを実装するサブクラスを返すことで、呼び出し元に影響を与えることなくメソッドの要件を満たすことができます。
    ここに画像の説明を挿入
    ここに画像の説明を挿入

2.5.3MessageDigest.getInstance()方法

ここに画像の説明を挿入

同じことがMessageDigest.getInstance()メソッドにも当てはまります。たとえば、MessageDigest.getInstance("MD5");MD5アルゴリズムを取得できます。

そして、Effective Javaの本、第2章、第1条はです用静态工厂方法代替构造器


2022年の正月4日目の早朝に完成。

おすすめ

転載: blog.csdn.net/MrYushiwen/article/details/122778335