シンプルファクトリーはデザインパターンではありません。オブジェクトの作成をクライアント コードから切り離すだけです。言い換えれば、シンプル ファクトリは、インスタンス化ロジックを別のクラスに移動することによって、オブジェクトのインスタンス化をカプセル化します。
シンプル ファクトリは、ファクトリ パターンと混同されることがよくあります。それらの違いを明確にするために、Simple Factory を研究していきます。また、Simple Factory を学習すると、Factory パターンを簡単に理解できるようになります。
具体的な実装へのプログラミングは、アプリケーションの保守が非常に困難になるため、避けるべきです。インターフェイスに合わせてプログラムすることが常に望ましいです。クライアント コードで具象クラスをインスタンス化する場合、Simple Factory はオブジェクトの作成をクライアントから分離できるため、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; }
問題は、インターフェイスではなく実装に向かってコーディングしていることです。どこ? if ステートメントを使用し、ハンバーガーの種類に基づいて具象クラスをインスタンス化します。
なぜそれが問題なのでしょうか?私たちのクライアント コードはオブジェクト作成と密接に結合しているため、柔軟性が低下します。フィッシュバーガーをもう販売しないで、ベジバーガーの販売を開始するとします。クライアントコードにアクセスして変更する必要があります。つまり、変更が禁止されていません。
この問題を解決するには、オブジェクトの作成のみを担当する別のクラスを作成します。そうすれば、クライアント コードはオブジェクトの作成について心配する必要がなくなり、抽象化に依存できるようになります。この技術は 「変化するものをカプセル化する」 として知られています。具体的なオブジェクトのインスタンス化に関するコードは頻繁に変更されると予想されますが、prepareBun()、grillPatty()、addToppings()、wrap() プロセスは将来的にすべてのハンバーガーで同じままになる可能性があります。
シンプル ファクトリの利点は、他のクラスで再利用できることです。 SimpleBurgerFactory.createBurger() メソッドを使用する BurgerRestaurant、BurgerCateringShop などの他のクライアント クラスがある可能性があります。
クライアント
クライアントは SimpleBurgerFactory を通じて特定のバーガー オブジェクトをインスタンス化します。クライアントの観点から見ると、どの具体的なバーガーが作成されるかはわかりません。つまり、オブジェクト作成ロジックはクライアントから切り離されています。
シンプルバーガーファクトリー
このクラスは、さまざまなもの、この場合はオブジェクト作成ロジックをカプセル化します。 createBurger() は、クライアントがこのクラスを使用してオブジェクトをインスタンス化したいため、静的メソッドとして宣言されています (もちろん、インスタンス化する前にインスタンスを持つことはできません)。 createBurger() は BurgerType 列挙型を受け入れて、作成するハンバーガーの種類を決定します。
バーガー
この抽象クラスは、すべてのバーガー間で共通のインターフェイスを提供し、デフォルトの動作を定義します。
バーガーのサブクラス
弊社の具体的な製品をご紹介します。 Burger クラスを拡張する限り、メソッドをオーバーライドすることで特定の動作を実装できます。
public enum BurgerType { BEEF, CHICKEN, FISH, VEGGIE }
// Abstract Product public abstract class Burger { public BurgerType burgerType; public Listtoppings = 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; Listitems = List.of("lettuce", "pickle slices", "tomato slice", "BBQ sauce"); toppings.addAll(items); } }
// Concrete product public class VeggieBurger extends Burger { public VeggieBurger() { burgerType = BurgerType.VEGGIE; Listitems = 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; } }
出力:
Preparing a bun Grill a VEGGIE patty Add smoked paprika Add garlic chips Add crushed walnuts Add veggie sauce Wrapping paper shouldn't print any meats but vegetables com.factories.simpleFactory.VeggieBurger@9807454
すべてのデザイン パターンの実装をここで確認できます。
GitHub リポジトリ
追記
技術ブログを書くのは初めてです。文章を改善するためのアドバイスや、わかりにくい点がある場合は、コメントを残してください。
読んでいただきありがとうございます:)
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3