首頁 > Java > java教程 > 簡單工廠

簡單工廠

Barbara Streisand
發布: 2024-11-24 11:40:11
原創
362 人瀏覽過

什麼是簡單工廠?

簡單工廠不是設計模式。它只是將物件創建與客戶端程式碼解耦。換句話說,簡單工廠透過將實例化邏輯移至單獨的類別來封裝物件實例化。

簡單工廠常與工廠模式混淆。我們將研究簡單工廠來闡明它們的差異。另外,學習簡單工廠可以幫助我們輕鬆理解工廠模式。

簡單工廠可以解決什麼問題?

應避免對具體實作進行編程,因為這會使應用程式非常難以維護。對介面進行程式設計總是更好的選擇。如果您在客戶端程式碼中實例化一個具體類,那麼簡單工廠會派上用場,因為簡單工廠可以將物件建立與客戶端分離。這使得我們的應用程式更具可擴展性和可維護性。

問題

我們正在為漢堡店開發系統。系統需要製作牛肉漢堡、雞肉漢堡等各種漢堡。

我們的第一次嘗試是這樣的:

// 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()過程可能會保持不變。
簡單工廠的優點是可以被其他類別重複使用。我們可能有其他客戶端類別,例如 BurgerRestaurant、BurgerCateringShop,它們將使用 SimpleBurgerFactory.createBurger() 方法。

Simple Factory

  1. 客戶
    客戶端透過SimpleBurgerFactory實例化特定的漢堡物件。請注意,從客戶端角度來看,我們不知道將創建哪個特定漢堡,也就是說,物件創建邏輯現在與客戶端解耦。

  2. 簡單漢堡工廠
    這個類別封裝了不同的內容,在本例中是物件創建邏輯! 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方法來代替。

與工廠模式的比較

  • 簡單工廠中,通常有一個工廠類別來決定創建哪種類型的產品,而工廠模式可能會引入多個工廠。
  • 簡單工廠經常使用靜態方法創建對象,呼叫容易但擴展困難。另一方面,工廠方法在超類別中使用抽象方法,它充當所有工廠和子類別的接口,將為物件實例化提供具體的實現。

您可以在這裡查看所有設計模式的實作。
GitHub 儲存庫


附註
我是剛開始寫科技博客,如果您對我的寫作有什麼建議,或者有任何困惑的地方,請留言!
感謝您的閱讀:)

以上是簡單工廠的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板