単純な工場はデザインパターンではありません。オブジェクトの作成をクライアント コードから切り離すだけです。言い換えれば、シンプル ファクトリは、インスタンス化ロジックを別のクラスに移動することによって、オブジェクトのインスタンス化をカプセル化します。
シンプル ファクトリは、ファクトリ パターンとよく混同されます。それらの違いを明確にするために、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 などの他のクライアント クラスがある可能性があります。
クライアント
クライアントは SimpleBurgerFactory を通じて特定のバーガー オブジェクトをインスタンス化します。クライアントの観点から見ると、どの具体的なバーガーが作成されるかはわかりません。つまり、オブジェクト作成ロジックはクライアントから切り離されています。
SimpleBurgerFactory
このクラスは、さまざまなもの、この場合はオブジェクト作成ロジックをカプセル化します。 createBurger() は、クライアントがこのクラスを使用してオブジェクトをインスタンス化したいため、静的メソッドとして宣言されています (もちろん、インスタンス化する前にインスタンスを持つことはできません)。 createBurger() は BurgerType 列挙型を受け入れて、作成するハンバーガーの種類を決定します。
バーガー
この抽象クラスは、すべてのバーガー間で共通のインターフェイスを提供し、デフォルトの動作を定義します。
ハンバーガーのサブクラス
弊社の具体的な製品をご紹介します。 Burger クラスを拡張する限り、メソッドをオーバーライドすることで特定の動作を実装できます。
// 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; } }
ここですべてのデザイン パターンの実装を確認できます。
GitHub リポジトリ
追伸
技術ブログを書くのは初めてです。文章を改善するためのアドバイスや、わかりにくい点がある場合は、コメントを残してください。
読んでいただきありがとうございます:)
以上がシンプルファクトリーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。