目錄
- 一、簡單工廠模式(Simple Factory Pattern)
- 二、工廠方法模式(Factory Method Pattern)
- 三、抽象工廠模式(Abstract Factory Pattern)
- 四、三者對比總結
- 五、選擇建議
- 如果這篇文章對你有所幫助,渴望獲得你的一個點贊!
抽象工廠模式、簡單工廠模式和工廠方法模式都是創建型設計模式,它們的核心目的都是將對象的創建和使用分離,但在實現復雜度、靈活性和應用場景上存在顯著差異。以下從定義、結構、適用場景和代碼示例四個方面進行對比分析:
一、簡單工廠模式(Simple Factory Pattern)
定義與結構
- 定義:簡單工廠模式是一種創建對象的方式,它將對象的創建邏輯封裝在一個工廠類中,通過傳入參數決定創建哪種產品。
- 核心角色:
- 工廠類(Factory):負責創建產品的靜態方法。
- 抽象產品(Product):定義產品的接口。
- 具體產品(ConcreteProduct):實現抽象產品接口。
適用場景
- 產品種類較少且創建邏輯簡單。
- 客戶端只需通過參數指定需要創建的產品,不關心創建細節。
代碼示例
// 抽象產品
class Shape {
public:virtual void draw() = 0;virtual ~Shape() = default;
};// 具體產品
class Circle : public Shape {
public:void draw() override { std::cout << "Circle::draw()" << std::endl; }
};class Rectangle : public Shape {
public:void draw() override { std::cout << "Rectangle::draw()" << std::endl; }
};// 簡單工廠
class ShapeFactory {
public:static std::unique_ptr<Shape> createShape(const std::string& type) {if (type == "circle") return std::make_unique<Circle>();if (type == "rectangle") return std::make_unique<Rectangle>();return nullptr; // 錯誤處理}
};// 客戶端使用
void client() {auto circle = ShapeFactory::createShape("circle");circle->draw(); // 輸出: Circle::draw()
}
特點
- 優點:實現簡單,將對象創建集中管理。
- 缺點:工廠類職責過重,新增產品需修改工廠類,違反開閉原則。
二、工廠方法模式(Factory Method Pattern)
定義與結構
- 定義:工廠方法模式定義創建對象的接口,讓子類決定實例化哪個類。工廠方法將產品的創建延遲到子類。
- 核心角色:
- 抽象工廠(AbstractFactory):聲明工廠方法,返回抽象產品。
- 具體工廠(ConcreteFactory):實現工廠方法,創建具體產品。
- 抽象產品(Product):定義產品的接口。
- 具體產品(ConcreteProduct):實現抽象產品接口。
適用場景
- 當一個類不知道它所需要的對象的類時(如框架設計)。
- 當一個類希望由其子類來指定創建對象時。
- 當類將創建對象的職責委托給多個子類中的某一個,并且希望在運行時動態指定時。
代碼示例
// 抽象產品
class Product {
public:virtual void operation() = 0;virtual ~Product() = default;
};// 具體產品
class ConcreteProductA : public Product {
public:void operation() override { std::cout << "ConcreteProductA::operation()" << std::endl; }
};class ConcreteProductB : public Product {
public:void operation() override { std::cout << "ConcreteProductB::operation()" << std::endl; }
};// 抽象工廠
class Factory {
public:virtual std::unique_ptr<Product> createProduct() = 0;virtual ~Factory() = default;
};// 具體工廠
class ConcreteFactoryA : public Factory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductA>();}
};class ConcreteFactoryB : public Factory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductB>();}
};// 客戶端使用
void client(Factory& factory) {auto product = factory.createProduct();product->operation();
}// 使用示例
int main() {ConcreteFactoryA factoryA;client(factoryA); // 輸出: ConcreteProductA::operation()ConcreteFactoryB factoryB;client(factoryB); // 輸出: ConcreteProductB::operation()
}
特點
- 優點:符合開閉原則,新增產品只需添加新的具體工廠,無需修改抽象工廠和客戶端。
- 缺點:工廠子類過多時會導致代碼復雜度增加。
三、抽象工廠模式(Abstract Factory Pattern)
定義與結構
- 定義:抽象工廠模式提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
- 核心角色:
- 抽象工廠(AbstractFactory):聲明創建多個抽象產品的方法。
- 具體工廠(ConcreteFactory):實現抽象工廠的方法,創建一組具體產品。
- 抽象產品族(AbstractProduct):定義多個產品的接口。
- 具體產品(ConcreteProduct):實現抽象產品接口。
適用場景
- 系統需要獨立于產品的創建、組合和表示時。
- 系統需要使用多個產品族中的一個,且產品之間有依賴關系。
- 需要動態切換產品系列時(如跨平臺 UI、主題系統)。
代碼示例
// 抽象產品A
class AbstractProductA {
public:virtual void operationA() = 0;virtual ~AbstractProductA() = default;
};// 具體產品A1
class ProductA1 : public AbstractProductA {
public:void operationA() override { std::cout << "ProductA1::operationA()" << std::endl; }
};// 具體產品A2
class ProductA2 : public AbstractProductA {
public:void operationA() override { std::cout << "ProductA2::operationA()" << std::endl; }
};// 抽象產品B
class AbstractProductB {
public:virtual void operationB() = 0;virtual ~AbstractProductB() = default;
};// 具體產品B1
class ProductB1 : public AbstractProductB {
public:void operationB() override { std::cout << "ProductB1::operationB()" << std::endl; }
};// 具體產品B2
class ProductB2 : public AbstractProductB {
public:void operationB() override { std::cout << "ProductB2::operationB()" << std::endl; }
};// 抽象工廠
class AbstractFactory {
public:virtual std::unique_ptr<AbstractProductA> createProductA() = 0;virtual std::unique_ptr<AbstractProductB> createProductB() = 0;virtual ~AbstractFactory() = default;
};// 具體工廠1
class ConcreteFactory1 : public AbstractFactory {
public:std::unique_ptr<AbstractProductA> createProductA() override {return std::make_unique<ProductA1>();}std::unique_ptr<AbstractProductB> createProductB() override {return std::make_unique<ProductB1>();}
};// 具體工廠2
class ConcreteFactory2 : public AbstractFactory {
public:std::unique_ptr<AbstractProductA> createProductA() override {return std::make_unique<ProductA2>();}std::unique_ptr<AbstractProductB> createProductB() override {return std::make_unique<ProductB2>();}
};// 客戶端使用
void client(AbstractFactory& factory) {auto productA = factory.createProductA();auto productB = factory.createProductB();productA->operationA();productB->operationB();
}// 使用示例
int main() {ConcreteFactory1 factory1;client(factory1); // 輸出: ProductA1::operationA() 和 ProductB1::operationB()ConcreteFactory2 factory2;client(factory2); // 輸出: ProductA2::operationA() 和 ProductB2::operationB()
}
特點
- 優點:將產品族的創建封裝,保證產品間的兼容性;易于切換產品系列。
- 缺點:新增產品族需修改抽象工廠及其所有子類,違反開閉原則;實現復雜。
四、三者對比總結
維度 | 簡單工廠模式 | 工廠方法模式 | 抽象工廠模式 |
---|---|---|---|
核心思想 | 將對象創建邏輯封裝在一個工廠類中 | 定義創建對象的接口,由子類實現具體創建邏輯 | 提供創建一系列相關產品的接口,無需指定具體類 |
工廠數量 | 一個工廠類 | 一個抽象工廠和多個具體工廠 | 一個抽象工廠和多個具體工廠 |
產品數量 | 一個產品等級結構 | 一個產品等級結構 | 多個產品等級結構(產品族) |
擴展性 | 新增產品需修改工廠類,違反開閉原則 | 新增產品只需添加新的具體工廠,符合開閉原則 | 新增產品族需修改抽象工廠,違反開閉原則 |
適用場景 | 產品種類少且創建邏輯簡單 | 需要靈活擴展創建邏輯的場景 | 創建相互依賴的產品族的場景 |
復雜度 | 簡單 | 中等 | 復雜 |
五、選擇建議
- 優先使用簡單工廠:當產品種類少且創建邏輯固定時。
- 使用工廠方法:當需要擴展性,且產品屬于同一等級結構時。
- 使用抽象工廠:當需要創建多個相關產品,且產品間有依賴關系時。
在實際應用中,可根據需求靈活組合這些模式,例如在抽象工廠中使用工廠方法實現具體產品的創建,或使用簡單工廠管理產品注冊。