在看这篇文章之前,请先看看“简单工厂模式”和“工厂方法模式”这两篇博文,会更有助于理解。我们现在已经知道,简单工厂模式就是用一个简单工厂去创建多个产品,工厂方法模式是每一个具体的工厂只生产一个具体的产品,然后这些具体的工厂都以一个抽象的工厂作为基类。
那么抽象工厂模式是什么呢,抽象工厂模式让一个具体的工厂可以生产多类的产品,也就是它从工厂方法模式种的一厂一产品,变成了一厂多产品的模式。有朋友问了,简单工厂模式不就是一厂多产品么,没错聪明的你发现了问题。但是简单工厂模式,它只有一个唯一的厂。而抽象工厂模式,却可以根据基类的抽象工厂,派生出N多个厂,这就是其本质的区别。
显然,这三个工厂模式的复杂度是逐渐增加的。这也是我们在进行软件设计的时候做选择的一个重要指标,针对我们具体应用场景的复杂度来选择对应的设计模式。尽量不要用一个复杂的设计模式去解决简单的问题,当然,简单的设计模式也无法很好的适配复杂的业务场景。
1.示例代码
//抽象工厂代码
#include <iostream>
using namespace std;
//抽象产品A
class AbstractProductA {
public:
virtual ~AbstractProductA() {}
virtual void Operation() = 0;
};
//具体产品A1
class ProductA1 : public AbstractProductA {
public:
void Operation() {
cout << "ProductA1" << endl;
}
};
//具体产品A2
class ProductA2 : public AbstractProductA {
public:
void Operation() {
cout << "ProductA2" << endl;
}
};
//抽象产品B
class AbstractProductB {
public:
virtual ~AbstractProductB() {}
virtual void Operation() = 0;
};
//具体产品B1
class ProductB1 : public AbstractProductB {
public:
void Operation() {
cout << "ProductB1" << endl;
}
};
//具体产品B2
class ProductB2 : public AbstractProductB {
public:
void Operation() {
cout << "ProductB2" << endl;
}
};
//抽象工厂
class AbstractFactory {
public:
virtual AbstractProductA* CreateProductA() = 0;
virtual AbstractProductB* CreateProductB() = 0;
virtual ~AbstractFactory() {}
};
//具体工厂1:生产产品A1和B1
class ConcreteFactory1 : public AbstractFactory {
public:
ProductA1* CreateProductA() {
return new ProductA1();
}
ProductB1* CreateProductB() {
return new ProductB1();
}
};
//具体工厂2:生产产品A2和B2
class ConcreteFactory2 : public AbstractFactory {
public:
ProductA2* CreateProductA() {
return new ProductA2();
}
ProductB2* CreateProductB() {
return new ProductB2();
}
};
int main() {
//示例代码就不判空了
AbstractFactory* factory1 = new ConcreteFactory1();
// 具体工厂创建对应的具体产品
AbstractProductA* productA_from_factory1 = factory1->CreateProductA(); // 工厂1创建产品A
AbstractProductB* productB_from_factory1 = factory1->CreateProductB(); // 工厂1创建产品B
productA_from_factory1->Operation(); // ProductA1
productB_from_factory1->Operation(); // ProductB1
AbstractFactory* factory2 = new ConcreteFactory2();
AbstractProductA* productA_from_factory2 = factory2->CreateProductA(); // 工厂2创建产品A
AbstractProductB* productB_from_factory2 = factory2->CreateProductB(); // 工厂2创建产品B
productA_from_factory2->Operation(); // ProductA2
productB_from_factory2->Operation(); // ProductB2
delete productA_from_factory1;
delete productA_from_factory2;
delete factory1;
delete productB_from_factory1;
delete productB_from_factory2;
delete factory2;
return 0;
}
2.组成结构
工厂方法模式包含的4个角色:
Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的父类。(这里需要特别说明的是,这个产品的抽象类与工厂的具体类是绑定的,也就是factory1对应一个抽象产品类product1,这是抽象工厂与工厂方法这两个模式最大的区别)
ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
Factroy(抽象工厂):在抽象工厂类中声明了工厂方法(Factory method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法,并可由客户端调用,返回一个具体产品类的实例。
3.工厂方法与抽象工厂对比
工厂方法模式:
- 一个抽象产品类,可以派生出多个具体产品类。
- 一个抽象工厂类,可以派生出多个具体工厂类。
- 每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
- 一个抽象产品类,可以派生出多个具体产品类。
- 一个抽象工厂类,可以派生出多个具体工厂类。
- 每个具体工厂类只能创建一个具体产品类的实例。
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
4.总结
所有的工厂模式其核心目的就是为了让对象的创建和使用分离,方便扩展。越是复杂的模式代码层次越多,可读性也变差。因此在选择设计模式的时候需要根据具体的业务场景来确定,不是越复杂的越好,也不是越简单的越好。