ホームページ >Java >&#&チュートリアル >ファクトリーパターン

ファクトリーパターン

Linda Hamilton
Linda Hamiltonオリジナル
2024-11-20 01:01:03652ブラウズ

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

ファクトリ パターンは、オブジェクトを作成するためのインターフェイスを定義する作成パターンですが、どのクラスをインスタンス化するかをサブクラスに決定させます。ファクトリ パターンでは、クラスのインスタンス化をサブクラスに延期できます。

いつ使用しますか?

「product」継承階層があり、そこに他のプロダクトを追加できる場合は、Factory パターンを使用します。 (Product は Factory メソッドによって返されるオブジェクトを参照します)

問題

Simple Factory について知らない場合は、事前に勉強しておくことをお勧めします。リソースはたくさんありますが、私のブログはここにあります。

Factory Pattern

以前、Simple Factory を導入し、オブジェクトの作成をクライアント コードから切り離しながら、さまざまなハンバーガーを生産できました。私たちのハンバーガー ショップは利益を得ることができたので、今度は別のエリアで他のハンバーガー ショップを立ち上げたいと考えています。

orderBurger メソッドは、顧客にハンバーガーを販売するプロセスを定義します。

// This is our Client
public class BurgerShop {

    public Burger orderBurger(BurgerType type) {
        // Factory is responsible for object creation
        Burger burger = SimpleBurgerFactory.createBurger(type);

        burger.prepareBun();
        burger.grillPatty();
        burger.addToppings();
        burger.wrap();

        return burger;
    }
}

これは全く問題ありませんが、他のハンバーガーショップを立ち上げたらどうなるでしょうか? 「SeaSideBurgerShop」を起動すると、SeaSideBurgerShop クラスを作成し、独自の orderBurger() を定義します。問題は、トッピングを追加するのを忘れたり、間違った順序で作業を行ったりする可能性があることです。

問題のある SeaSideBurgerShop:

public class SeaSideBurgerShop {

    public Burger orderBurger(BurgerType type) {
        Burger burger = SimpleBurgerFactory.createBurger(type);

        burger.prepareBun();
        burger.wrap(); // Wrap a burger before grilling a patty??
        burger.grillPatty();
        // They forget to add toppings!!

        return burger;
    }
}

これを防ぐには、プロセスを実行する順序と何を行うかを定義しつつ、柔軟な対応を可能にするフレームワークがバーガー ショップに必要です。

解決

Factory Pattern

  1. バーガーショップ
    この抽象クラスには、orderBurger() と createBurger() という 2 つのメソッドがあります。 orderBurger() は、何を行うか、どの順序でプロセスを実行するかを定義します。これにより、バーガーショップが工程を忘れたり、工程順序を間違えたりすることを防ぎます。 creatBurger() は、どの種類のハンバーガーを作るかをサブクラスに決定させる抽象メソッドです。

  2. BurgerShop サブクラス
    これらのコンクリート BurgerShop は、コンクリート バーガーの作成を担当します。 BurgerShop を拡張する各サブクラスは、createBurger().

  3. の独自の実装を定義します。
  4. バーガー
    この抽象クラスは、すべてのバーガー間で共通のインターフェイスを提供し、デフォルトの動作を定義します。

  5. ハンバーガーのサブクラス
    弊社の具体的な製品をご紹介します。 Burger クラスを拡張する限り、メソッドをオーバーライドすることで特定の動作を実装できます。

構造

Factory Pattern

Javaでの実装

// This is our Client
public class BurgerShop {

    public Burger orderBurger(BurgerType type) {
        // Factory is responsible for object creation
        Burger burger = SimpleBurgerFactory.createBurger(type);

        burger.prepareBun();
        burger.grillPatty();
        burger.addToppings();
        burger.wrap();

        return burger;
    }
}

public class SeaSideBurgerShop {

    public Burger orderBurger(BurgerType type) {
        Burger burger = SimpleBurgerFactory.createBurger(type);

        burger.prepareBun();
        burger.wrap(); // Wrap a burger before grilling a patty??
        burger.grillPatty();
        // They forget to add toppings!!

        return burger;
    }
}
public enum BurgerType {
    BEEF,
    CHICKEN,
    FISH,
    VEGGIE
}
public abstract class Burger {
    public BurgerType type;
    public List<String> toppings = new ArrayList<>();

    public void prepareBun() {
        System.out.println("Preparing a bun");
    }

    public void grillPatty() {
        if (type == null) {
            throw new IllegalStateException("pattyType is undefined");
        }
        System.out.println("Grill a " + type + " patty");
    }

    public void addToppings() {
        for (String item : toppings) {
            System.out.println("Add " + item);
        }
    }

    public void wrap() {
        System.out.println("Wrap a burger up");
    }
}
public class CityStyleBeefBurger extends Burger {

    public CityStyleBeefBurger() {
        type = BurgerType.BEEF;
        List<String> items = List.of("lettuce", "pickle slices", "tomato slice", "BBQ sauce");
        toppings.addAll(items);
    }
}
public class CityStyleVeggieBurger extends Burger {

    public CityStyleVeggieBurger() {
        type = BurgerType.VEGGIE;
        List<String> items = List.of("smoked paprika", "garlic chips", "crushed walnuts", "veggie sauce");
        toppings.addAll(items);
    }
}
public class SeaSideStyleBeefBurger extends Burger {

    public SeaSideStyleBeefBurger() {
        type = BurgerType.BEEF;
        // Localized toppings for beef burger in seaside area
        List<String> items = List.of("lettuce", "pickle slices", "tomato slice", "salty sauce");
        toppings.addAll(items);
    }

    // Uses localized wrapping paper
    @Override
    public void wrap() {
        System.out.println("Wrap with a paper with nice sea scenery");
    }
}
public class SeaSideStyleFishBurger extends Burger {

    public SeaSideStyleFishBurger() {
        type = BurgerType.FISH;
        // Localized toppings for fish burger in seaside area
        List<String> items = List.of("red onion slices", "salty sauce", "fried shrimps");
        toppings.addAll(items);
    }

    // Uses localized wrapping paper
    @Override
    public void wrap() {
        System.out.println("Wrap with a paper with nice sea scenery");
    }
}
public abstract class BurgerShop {

    // This method provides a framework for each burger shops to order burgers
    public Burger orderBurger(BurgerType type) {
        Burger burger = createBurger(type);

        burger.prepareBun();
        burger.grillPatty();
        burger.addToppings();
        burger.wrap();

        return burger;
    }

    // This is our factory method. Subclasses will override this method,
    // provide their own implementation, determine which kind of burger gets made.
    public abstract Burger createBurger(BurgerType type);
}

出力:

public class CityBurgerShop extends BurgerShop {

    @Override
    public Burger createBurger(BurgerType type) {
        return switch (type) {
            case BEEF -> new CityStyleBeefBurger();
            case VEGGIE -> new CityStyleVeggieBurger();
            default -> throw new IllegalArgumentException("unknown city burger type");
        };
    }
}

落とし穴

  • 抽象クリエーターまたは抽象プロダクトを拡張する多数のクラスを作成する必要があるため、実装が複雑です。

シンプルファクトリーとの比較

  • シンプル ファクトリでは、通常、作成する製品のタイプを決定するファクトリ クラスが 1 つありますが、ファクトリ パターンでは複数のファクトリが導入される場合があります。
  • シンプル ファクトリでは、オブジェクトの作成に静的メソッドがよく使用されます。これにより、呼び出すのは簡単ですが、拡張するのが難しくなります。一方、Factory メソッドはスーパー クラスで抽象メソッドを使用し、すべてのファクトリとサブクラスのインターフェイスとして機能し、オブジェクトのインスタンス化のための具体的な実装を提供します。

ここですべてのデザイン パターンの実装を確認できます。
GitHub リポジトリ


追伸
技術ブログを書くのは初めてです。文章を改善するためのアドバイスや、わかりにくい点がある場合は、コメントを残してください。
読んでいただきありがとうございます:)

以上がファクトリーパターンの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。