設計模式之工廠模式(學習筆記)
定義
工廠方法模式是一種創建型設計模式,它定義了一個用于創建對象的接口,但由子類來決定實例化哪一個類。工廠方法使得類的實例化延遲到子類,這樣可以讓客戶端在不需要知道具體類的情況下創建對象。工廠方法模式通過使用繼承和多態性,允許子類來控制對象的創建方式,能夠更好地應對對象創建的復雜性和變化性。
為什么使用工廠方法模式?
1. 遵循開閉原則
- 工廠方法模式通過引入新的子類來擴展系統,而不需要修改現有代碼,從而符合開閉原則。
2. 更靈活的對象創建
- 工廠方法模式將對象創建延遲到子類,這樣可以通過重寫工廠方法來定制對象的創建過程。
3. 支持產品族的擴展
- 當系統中有多個產品等級結構時,可以通過工廠方法模式來管理不同等級的產品創建過程。
實現步驟
1. 定義抽象產品類
- 定義所有具體產品類的共同接口,客戶端將通過這個接口來使用具體產品。
2. 實現具體產品類
- 實現產品接口的具體產品類,這些類包含了產品的實際業務邏輯。
3. 定義抽象工廠類
- 定義一個抽象工廠類,包含一個用于創建產品對象的抽象方法,子類將實現該方法來創建具體產品對象。
4. 實現具體工廠類
- 繼承抽象工廠類并實現其抽象方法,具體工廠類負責創建具體產品對象。
優缺點和適用場景
優點
1. 遵循開閉原則
- 新增產品時無需修改已有系統代碼,符合開閉原則。
2. 更靈活的對象創建
- 子類可以通過重寫工廠方法來定制對象的創建過程,提供更靈活的對象創建機制。
3. 支持產品族擴展
- 能夠很好地應對產品族的擴展和變化。
缺點
1. 增加類的數量
- 每新增一種產品類型,都需要增加一個具體工廠類,可能導致系統中類的數量增加。
2. 復雜度增加
- 與簡單工廠模式相比,工廠方法模式引入了更多的類和接口,增加了系統的復雜性。
適用場景
1. 系統需要靈活和可擴展的對象創建機制
- 當系統需要靈活地創建對象,并且能夠應對產品族的變化時,可以使用工廠方法模式。
2. 遵循開閉原則
- 當系統需要遵循開閉原則,避免修改現有代碼來擴展新功能時,適合使用工廠方法模式。
工廠方法模式與簡單工廠模式的對比
1. 職責分配
- 簡單工廠模式將對象創建集中在一個工廠類中,而工廠方法模式將對象創建延遲到具體子類中,職責更加分散。
2. 開閉原則
- 簡單工廠模式在引入新產品時需要修改工廠類,違背了開閉原則;工廠方法模式通過新增具體工廠類來擴展新產品,符合開閉原則。
3. 復雜性
- 簡單工廠模式結構較為簡單,適用于創建邏輯不復雜的場景;工廠方法模式結構較為復雜,適用于創建邏輯復雜且需要靈活擴展的場景。
咖啡店的例子
我們可以使用工廠方法模式來實現咖啡店不同類型咖啡的創建。
#include <iostream> #include <memory> #include <string> // 抽象產品類:咖啡 class Coffee { public: virtual ~Coffee() {} virtual std::string getDescription() const = 0; virtual double cost() const = 0; }; // 具體產品類:美式咖啡 class Americano : public Coffee { public: std::string getDescription() const override { return "Americano"; } double cost() const override { return 5.0; } }; // 具體產品類:拿鐵咖啡 class Latte : public Coffee { public: std::string getDescription() const override { return "Latte"; } double cost() const override { return 6.0; } }; // 抽象工廠類 class CoffeeFactory { public: virtual ~CoffeeFactory() {} virtual std::shared_ptr<Coffee> createCoffee() const = 0; }; // 具體工廠類:美式咖啡工廠 class AmericanoFactory : public CoffeeFactory { public: std::shared_ptr<Coffee> createCoffee() const override { return std::make_shared<Americano>(); } }; // 具體工廠類:拿鐵咖啡工廠 class LatteFactory : public CoffeeFactory { public: std::shared_ptr<Coffee> createCoffee() const override { return std::make_shared<Latte>(); } }; int main() { // 創建美式咖啡 std::shared_ptr<CoffeeFactory> americanoFactory = std::make_shared<AmericanoFactory>(); std::shared_ptr<Coffee> americano = americanoFactory->createCoffee(); std::cout << "Description: " << americano->getDescription() << ", Cost: " << americano->cost() << " RMB" << std::endl; // 創建拿鐵咖啡 std::shared_ptr<CoffeeFactory> latteFactory = std::make_shared<LatteFactory>(); std::shared_ptr<Coffee> latte = latteFactory->createCoffee(); std::cout << "Description: " << latte->getDescription() << ", Cost: " << latte->cost() << " RMB" << std::endl; return 0; }

浙公網安備 33010602011771號