5分鐘學設計模式:工廠方法,讓你的程式碼像搭積木一樣簡單!

知微之见發表於2024-05-17

大家好,我是知微。

上一次的美食街之旅中,我們探討了簡單工廠模式。今天,讓我們繼續在美食街的夜色中,探索工廠方法模式的奧秘。

第一幕:美食街的繁華

美食街上,小吃攤的生意越來越火,攤主們為了滿足顧客的多樣化需求,開始提供更多種類的小吃。

顧客(你):老闆,聽說你們這除了煎餅果子,還有其他好吃的?

老闆:對啊,我們最近推出了烤冷麵和章魚小丸子,都非常受歡迎!

顧客(你):聽起來不錯,那各來一份吧!

老闆:好嘞,馬上給您做!

用程式碼表示

class Snack {
public:
    virtual void serve() = 0;
    virtual ~Snack() {}
};

class RoastedColdNoodles : public Snack {
public:
    void serve() override {
        std::cout << "你的烤冷麵好了!" << std::endl;
    }
};

class OctopusBall : public Snack {
public:
    void serve() override {
        std::cout << "你的章魚小丸子好了!" << std::endl;
    }
};

// 簡單工廠
class SnackFactory {
public:
    static Snack* createSnack(const std::string& type) {
        if (type == "COLD_NOODLES") {
            return new RoastedColdNoodles();
        } else if (type == "OCTOPUS_BALL") {
            return new OctopusBall();
        }
        // ...其他小吃型別的建立
        return nullptr;
    }
};

第二幕:小吃攤的擴張

隨著生意越來越好,老闆一個人弄這麼多種類的小吃(簡單工廠模式,一個工廠做很多種類),很多時候都忙不過來,出餐速度慢了許多。

思考了幾天之後,老闆果斷做了決定,讓家人幫忙,多弄幾個攤位,每個攤位都負責自己的小吃(工廠方法模式每個工廠只做對應的產品),顧客可以直接去找他們喜歡的攤位。

顧客(你):老闆,我想吃手抓餅,但這家攤位只賣煎餅果子。

老闆:沒問題,我讓我家手抓餅攤位的老闆給你做。

顧客(你):這樣啊,那我就放心了。

用程式碼表示

// 抽象產品
class Snack {
public:
    virtual void serve() = 0;
    virtual ~Snack() {}
};

// 具體產品
class HandPies : public Snack {
public:
    void serve() override {
        std::cout << "你的手抓餅好了!" << std::endl;
    }
};

// 簡單工廠
class SnackFactory {
public:
    static Snack* createSnack(const std::string& type) {
        if (type == "HANDPIES") {
            return new HandPies();
        }
        // ...其他小吃型別的建立
        return nullptr;
    }
};

第三幕:小吃攤的專業化

老闆的決定很快帶來了變化,每個攤位都開始專注於自己的特色小吃,顧客可以直接向特定的攤位訂購。

顧客(你):我聽說這家的章魚小丸子特別好吃,我就直接來這家攤位了。

章魚小丸子老闆:歡迎光臨!我們的章魚小丸子是這條街上最好吃的,馬上就給您做。

顧客(你):太好了,我等不及要嚐嚐了。

用程式碼表示

// 抽象工廠
class SnackFactory {
public:
    virtual std::unique_ptr<Snack> createSnack() = 0;
    virtual ~SnackFactory() {}
};

// 具體工廠
class OctopusBallFactory : public SnackFactory {
public:
    std::unique_ptr<Snack> createSnack() override {
        return std::make_unique<OctopusBall>();
    }
};

// 客戶端程式碼
int main() {
    OctopusBallFactory factory;
    auto snack = factory.createSnack();
    snack->serve(); // 章魚小丸子老闆:歡迎光臨,我們的章魚小丸子是這條街上最好吃的!
    return 0;
}

第四幕:小吃攤的繁榮

美食街上的小吃攤變成了一家家各具特色的小吃店,每家店都有自己的招牌小吃,顧客可以根據自己的口味,選擇不同的店鋪品嚐小吃。

顧客(你):這條街上的小吃種類真多,每種都想嚐嚐。

老闆:是啊,我們每家店都有自己的特色,歡迎您常來嘗試。

顧客(你):我會的,下次再帶朋友一起來。

用程式碼表示

// 可以為每種小吃建立不同的工廠類
class RoastedColdNoodlesFactory : public SnackFactory {
public:
    std::unique_ptr<Snack> createSnack() override {
        return std::make_unique<RoastedColdNoodles>();
    }
};

class PancakeFactory : public SnackFactory {
    // ...實現
};

// ...其他小吃工廠類

結語

工廠方法模式透過定義一個建立小吃的介面,讓具體的工廠類負責生產具體的小吃產品。這樣,當需要新增小吃種類時,只需新增相應的工廠,而無需修改既有程式碼,提高了程式的可擴充套件性和可維護性。

工廠方法模式的優缺點

  • 優點

    • 提高了程式碼的擴充套件性,新增小吃種類無需修改原有程式碼。
    • 將物件的建立和使用分離,提高了程式碼的靈活性。
    • 利用多型,可以在執行時決定建立哪種型別的產品。
  • 缺點

    • 隨著產品種類的增加,可能需要建立很多工廠類,導致系統變得複雜。
    • 客戶端需要知道具體的工廠類名稱,可能降低了一些封裝性。

應用場景

  • 當系統由多個部分組成,且各部分都有共同的生產物件的需求時。
  • 當需要強調物件建立和物件使用分離的場景時。

總結來說,簡單工廠模式適合用於產品型別較少且不會頻繁增加的情況,而工廠方法模式則適合於產品型別較多且可能會頻繁增加的場合。

工廠方法模式透過使用多型減少了耦合,使得新增產品型別時,不需要修改工廠類,只需要新增相應的具體工廠類即可。

以上就是工廠方法模式的全部內容了,下一期,我們將帶來抽象工廠模式的精彩故事,敬請期待!

📢你的每一次👍點贊 ⭐收藏 📝評論,都是我更新的動力,如有錯誤請留言指正,非常感謝!

相關文章