1、描述
抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。
什么是 “系列对象”? 例如有这样一组的对象: 运输工具
+ 引擎
+ 控制器
。 它可能会有几个变体:
-
汽车
+内燃机
+方向盘
-
飞机
+喷气式发动机
+操纵杆
如果你的程序中并不涉及产品系列的话, 那就不需要抽象工厂。
优点:封装性,每个产品的实现类不是高层模块要关心的,它要关心的是什么?是接口,是抽象,它不关心对象是如何创建出来。
缺点:抽象工厂模式的最大缺点是产品族扩展非常困难。它严重违反了开闭原则。
2、结构图
- 抽象产品(AbstractProduct)为构成系列产品的一组不同但相关的产品声明接口。
- 具体产品(ConcreteProduct)是抽象产品的多种不同类型实现。
- 抽象工厂(AbstractFactory)接口声明了一组创建各种抽象产品的方法。
- 具体工厂(ConcreteFactory)实现抽象工厂的构建方法。每个具体工厂都对应特定产品变体,且仅创建此产品变体。
3、C++代码
#include <string>
#include <iostream>
// 系列产品中的特定产品必须有一个基础接口。所有产品变体都必须实现这个接口。
class AbstractProductA {
public:
virtual ~AbstractProductA(){};
virtual std::string UsefulFunctionA() const = 0;
};
// 具体产品由相应的具体工厂创建。
class ConcreteProductA1 : public AbstractProductA {
public:
std::string UsefulFunctionA() const override {
return "The result of the product A1.";
}
};
class ConcreteProductA2 : public AbstractProductA {
std::string UsefulFunctionA() const override {
return "The result of the product A2.";
}
};
// 这是另一个产品的基础接口。所有产品都可以互动,但是只有相同具体变体的产
// 品之间才能够正确地进行交互。
class AbstractProductB {
public:
virtual ~AbstractProductB(){};
//产品B可以做自己的事情
virtual std::string UsefulFunctionB() const = 0;
//。。但它也可以和产品A配合。抽象工厂确保它创建的所有产品都是相同的变体,因此是兼容的。
virtual std::string AnotherUsefulFunctionB(const AbstractProductA &collaborator) const = 0;
};
// 具体产品由相应的具体工厂创建。
class ConcreteProductB1 : public AbstractProductB {
public:
std::string UsefulFunctionB() const override {
return "The result of the product B1.";
}
//产品B1只能和产品A1一起正常工作。然而,它接受AbstractProductA的任何实例作为参数。
std::string AnotherUsefulFunctionB(const AbstractProductA &collaborator) const override {
const std::string result = collaborator.UsefulFunctionA();
return "The result of the B1 collaborating with ( " + result + " )";
}
};
class ConcreteProductB2 : public AbstractProductB {
public:
std::string UsefulFunctionB() const override {
return "The result of the product B2.";
}
//产品B2只能和产品A2一起正常工作。然而,它接受AbstractProductA的任何实例作为参数。
std::string AnotherUsefulFunctionB(const AbstractProductA &collaborator) const override {
const std::string result = collaborator.UsefulFunctionA();
return "The result of the B2 collaborating with ( " + result + " )";
}
};
// 抽象工厂接口声明了一组能返回不同抽象产品的方法。这些产品属于同一个系列
// 且在高层主题或概念上具有相关性。同系列的产品通常能相互搭配使用。系列产
// 品可有多个变体,但不同变体的产品不能搭配使用。
class AbstractFactory {
public:
virtual AbstractProductA *CreateProductA() const = 0;
virtual AbstractProductB *CreateProductB() const = 0;
};
// 具体工厂可生成属于同一变体的系列产品。工厂会确保其创建的产品能相互搭配
// 使用。具体工厂方法签名会返回一个抽象产品,但在方法内部则会对具体产品进
// 行实例化。
class ConcreteFactory1 : public AbstractFactory {
public:
AbstractProductA *CreateProductA() const override {
return new ConcreteProductA1();
}
AbstractProductB *CreateProductB() const override {
return new ConcreteProductB1();
}
};
// 每个具体工厂中都会包含一个相应的产品变体。
class ConcreteFactory2 : public AbstractFactory {
public:
AbstractProductA *CreateProductA() const override {
return new ConcreteProductA2();
}
AbstractProductB *CreateProductB() const override {
return new ConcreteProductB2();
}
};
// 客户端代码仅通过抽象类型使用工厂和产品。这让你无需修改任何工厂或产品子类就能将其传递给客户端代码。
void ClientCode(const AbstractFactory &factory) {
const AbstractProductA *product_a = factory.CreateProductA();
const AbstractProductB *product_b = factory.CreateProductB();
std::cout << product_b->UsefulFunctionB() << "\n";
std::cout << product_b->AnotherUsefulFunctionB(*product_a) << "\n";
delete product_a;
delete product_b;
}
int main() {
std::cout << "Client: Testing client code with the first factory type:\n";
ConcreteFactory1 *f1 = new ConcreteFactory1();
ClientCode(*f1);
delete f1;
std::cout << std::endl;
std::cout << "Client: Testing the same client code with the second factory type:\n";
ConcreteFactory2 *f2 = new ConcreteFactory2();
ClientCode(*f2);
delete f2;
return 0;
}
参考: