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

シンプルファクトリー

Barbara Streisand
Barbara Streisandオリジナル
2024-11-24 11:40:11315ブラウズ

シンプルファクトリーとは何ですか?

単純な工場はデザインパターンではありません。オブジェクトの作成をクライアント コードから切り離すだけです。言い換えれば、シンプル ファクトリは、インスタンス化ロジックを別のクラスに移動することによって、オブジェクトのインスタンス化をカプセル化します。

シンプル ファクトリは、ファクトリ パターンとよく混同されます。それらの違いを明確にするために、Simple Factory を研究していきます。また、Simple Factory を学習すると、Factory パターンを簡単に理解できるようになります。

シンプルファクトリーで解決できる問題とは?

具体的な実装へのプログラミングは、アプリケーションの保守が非常に困難になるため、避けるべきです。インターフェイスに合わせてプログラムすることが常に望ましいです。クライアント コードで具象クラスをインスタンス化する場合、Simple ファクトリはオブジェクトの作成をクライアントから分離できるため、Simple ファクトリが便利です。これにより、アプリケーションの拡張性と保守性が向上します。

問題

私たちはハンバーガーショップ向けのシステムを開発しています。システムは、ビーフバーガー、チキンバーガーなどのさまざまなバーガーを作成する必要があります。

最初の試みは次のようになります:

// Client orders a burger
Burger orderBurger(String type) {
    Burger burger;

    if (type.equals("beef")) {
        burger = new BeefBurger();
    } else if (type.equals("chicken")) {
        burger = new ChickenBurger();
    } else if (type.equals("fish")) {
        burger = new FishBurger();
    }

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

    return burger;
}

問題は、インターフェースではなく実装に向かってコーディングしていることです。どこ? if ステートメントを使用し、ハンバーガーの種類に基づいて具象クラスをインスタンス化します。
なぜそれが問題なのでしょうか?私たちのクライアント コードはオブジェクト作成と密接に結合しているため、柔軟性が低下します。フィッシュバーガーをもう販売しないで、ベジバーガーの販売を開始するとします。クライアントコードにアクセスして変更する必要があります。つまり、変更が禁止されていません。

解決

この問題を解決するには、オブジェクトの作成のみを担当する別のクラスを作成します。そうすれば、クライアント コードはオブジェクトの作成について心配する必要がなくなり、抽象化に依存できるようになります。この技術は 「変化するものをカプセル化する」 として知られています。具体的なオブジェクトのインスタンス化に関するコードは頻繁に変更されると予想されますが、prepareBun()、grillPatty()、addToppings()、wrap() のプロセスは将来的にすべてのハンバーガーで同じままになる可能性があります。
シンプル ファクトリの利点は、他のクラスで再利用できることです。 SimpleBurgerFactory.createBurger() メソッドを使用する BurgerRestaurant、BurgerCateringShop などの他のクライアント クラスがある可能性があります。

Simple Factory

  1. クライアント
    クライアントは SimpleBurgerFactory を通じて特定のバーガー オブジェクトをインスタンス化します。クライアントの観点から見ると、どの具体的なバーガーが作成されるかはわかりません。つまり、オブジェクト作成ロジックはクライアントから切り離されています。

  2. SimpleBurgerFactory
    このクラスは、さまざまなもの、この場合はオブジェクト作成ロジックをカプセル化します。 createBurger() は、クライアントがこのクラスを使用してオブジェクトをインスタンス化したいため、静的メソッドとして宣言されています (もちろん、インスタンス化する前にインスタンスを持つことはできません)。 createBurger() は BurgerType 列挙型を受け入れて、作成するハンバーガーの種類を決定します。

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

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

構造

Simple Factory

コード

// Client orders a burger
Burger orderBurger(String type) {
    Burger burger;

    if (type.equals("beef")) {
        burger = new BeefBurger();
    } else if (type.equals("chicken")) {
        burger = new ChickenBurger();
    } else if (type.equals("fish")) {
        burger = new FishBurger();
    }

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

    return burger;
}
public enum BurgerType {
    BEEF,
    CHICKEN,
    FISH,
    VEGGIE
}
// Abstract Product
public abstract class Burger {

    public BurgerType burgerType;
    public List<String> toppings = new ArrayList<>();

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

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

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

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

    public BeefBurger() {
        burgerType = BurgerType.BEEF;
        List<String> items = List.of("lettuce", "pickle slices", "tomato slice", "BBQ sauce");
        toppings.addAll(items);
    }
}
// Concrete product
public class VeggieBurger extends Burger {

    public VeggieBurger() {
        burgerType = BurgerType.VEGGIE;
        List<String> items = List.of("smoked paprika", "garlic chips", "crushed walnuts", "veggie sauce");
        toppings.addAll(items);
    }

    // Concrete product can implement specific behavior that differs from other products
    @Override
    public void wrap() {
        System.out.println("Wrapping paper shouldn't print any meats but vegetables");
    }
}
// Simple factory, responsible for instantiating an object
public class SimpleBurgerFactory {

    public static Burger createBurger(BurgerType type) {
        return switch (type) {
            case BEEF -> new BeefBurger();
            case CHICKEN -> new ChickenBurger();
            case FISH -> new FishBurger();
            case VEGGIE -> new VeggieBurger();
            default -> throw new IllegalArgumentException("unknown burger type");
        };
    }
}

出力:

public class Client {

    public static void main(String[] args) {
        Burger burger = orderBurger(BurgerType.VEGGIE);
        System.out.println(burger); // Check if the object is actually veggie burger
    }

    public static 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;
    }
}

落とし穴

  • オブジェクトのインスタンス化のための意思決定コードは、より複雑になる場合があります。そのような場合は、代わりに Factory メソッドを使用することを検討してください。

工場出荷時パターンとの比較

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

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


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

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

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