23种设计模式-抽象工厂(Abstract Factory)设计模式
文章目录
- 一.什么是抽象工厂设计模式?
- 二.抽象工厂模式的特点
- 三.抽象工厂模式的结构
- 四.抽象工厂模式的优缺点
- 五.抽象工厂模式的 C++ 实现
- 六.抽象工厂模式的 Java 实现
- 七.代码解析
- 八.总结
类图: 抽象工厂设计模式类图
一.什么是抽象工厂设计模式?
抽象工厂模式(Abstract Factory Pattern) 是一种创建型设计模式,它提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。
与工厂方法模式的区别在于,抽象工厂模式更注重产品族的概念,可以同时创建多个相关的产品对象。
二.抽象工厂模式的特点
- 多产品创建:可以创建一组相关联的对象(如按钮和文本框)。
- 解耦性强:客户端只需调用工厂接口创建对象,而不需要关心具体实现。
- 可扩展性:可以通过增加新的工厂子类来扩展产品系列。
三.抽象工厂模式的结构
- AbstractFactory(抽象工厂):声明了一组创建产品的方法。
- ConcreteFactory(具体工厂):实现抽象工厂的接口,创建具体的产品。
- AbstractProduct(抽象产品):定义产品的接口。
- ConcreteProduct(具体产品):实现抽象产品接口的具体类。
- Client(客户端):通过工厂接口与具体产品交互。
四.抽象工厂模式的优缺点
- 优点:
- 易于扩展:增加新的产品族只需增加对应的具体工厂类和产品类。
- 封装性强:客户端与具体产品实现解耦。
- 符合开闭原则:通过扩展具体工厂类来支持新产品。
- 缺点:
- 增加复杂性:每增加一个产品族,都需要新增具体工厂和产品类。
- 不支持单一产品族扩展:如果只想增加单个产品,可能需要修改抽象工厂接口。
五.抽象工厂模式的 C++ 实现
#include <iostream>
#include <memory>
using namespace std;
// 抽象产品A
class AbstractProductA {
public:
virtual void MethodA() const = 0;
virtual ~AbstractProductA() = default;
};
// 抽象产品B
class AbstractProductB {
public:
virtual void MethodB() const = 0;
virtual ~AbstractProductB() = default;
};
// 具体产品A1
class ConcreteProductA1 : public AbstractProductA {
public:
void MethodA() const override {
cout << "ConcreteProductA1::MethodA" << endl;
}
};
// 具体产品A2
class ConcreteProductA2 : public AbstractProductA {
public:
void MethodA() const override {
cout << "ConcreteProductA2::MethodA" << endl;
}
};
// 具体产品B1
class ConcreteProductB1 : public AbstractProductB {
public:
void MethodB() const override {
cout << "ConcreteProductB1::MethodB" << endl;
}
};
// 具体产品B2
class ConcreteProductB2 : public AbstractProductB {
public:
void MethodB() const override {
cout << "ConcreteProductB2::MethodB" << endl;
}
};
// 抽象工厂
class AbstractFactory {
public:
virtual unique_ptr<AbstractProductA> CreateProductA() const = 0;
virtual unique_ptr<AbstractProductB> CreateProductB() const = 0;
virtual ~AbstractFactory() = default;
};
// 具体工厂1
class ConcreteFactory1 : public AbstractFactory {
public:
unique_ptr<AbstractProductA> CreateProductA() const override {
return make_unique<ConcreteProductA1>();
}
unique_ptr<AbstractProductB> CreateProductB() const override {
return make_unique<ConcreteProductB1>();
}
};
// 具体工厂2
class ConcreteFactory2 : public AbstractFactory {
public:
unique_ptr<AbstractProductA> CreateProductA() const override {
return make_unique<ConcreteProductA2>();
}
unique_ptr<AbstractProductB> CreateProductB() const override {
return make_unique<ConcreteProductB2>();
}
};
// 客户端代码
void ClientCode(const AbstractFactory& factory) {
auto productA = factory.CreateProductA();
auto productB = factory.CreateProductB();
productA->MethodA();
productB->MethodB();
}
int main() {
cout << "Using ConcreteFactory1:" << endl;
ConcreteFactory1 factory1;
ClientCode(factory1);
cout << "Using ConcreteFactory2:" << endl;
ConcreteFactory2 factory2;
ClientCode(factory2);
return 0;
}
六.抽象工厂模式的 Java 实现
// 抽象产品A
interface ProductA {
void methodA();
}
// 抽象产品B
interface ProductB {
void methodB();
}
// 具体产品A1
class ConcreteProductA1 implements ProductA {
public void methodA() {
System.out.println("ConcreteProductA1::methodA");
}
}
// 具体产品A2
class ConcreteProductA2 implements ProductA {
public void methodA() {
System.out.println("ConcreteProductA2::methodA");
}
}
// 具体产品B1
class ConcreteProductB1 implements ProductB {
public void methodB() {
System.out.println("ConcreteProductB1::methodB");
}
}
// 具体产品B2
class ConcreteProductB2 implements ProductB {
public void methodB() {
System.out.println("ConcreteProductB2::methodB");
}
}
// 抽象工厂
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA1();
}
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA2();
}
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
// 客户端代码
public class AbstractFactoryDemo {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
productA1.methodA();
productB1.methodB();
AbstractFactory factory2 = new ConcreteFactory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA2.methodA();
productB2.methodB();
}
}
七.代码解析
- 抽象产品类:
- AbstractProductA 和 AbstractProductB 是抽象类,定义了各自的接口方法(如 MethodA 和 MethodB)。
- 具体产品类:
- ConcreteProductA1 和 ConcreteProductA2 实现了 AbstractProductA 接口,表示同一产品族中的不同产品。
- ConcreteProductB1 和 ConcreteProductB2 实现了 AbstractProductB 接口。
- 抽象工厂类:
- AbstractFactory 提供了创建产品的方法接口(CreateProductA 和 CreateProductB),由具体工厂实现。
- 具体工厂类:
- ConcreteFactory1 创建产品族 ConcreteProductA1 和 ConcreteProductB1。
- ConcreteFactory2 创建产品族 ConcreteProductA2 和 ConcreteProductB2。
- 客户端代码:
- 客户端通过抽象工厂创建产品,不需要知道具体工厂和产品的实现细节。
- 多态使得客户端代码具有很强的灵活性。
八.总结
抽象工厂模式在需要创建一组相关对象时非常有用,同时也很好地遵循了依赖倒置原则和开闭原则。通过抽象工厂,客户端只需关心工厂接口,而不需要了解具体产品的实现,从而实现了代码的解耦。尽管增加了系统的复杂性,但在复杂系统中,它可以显著提高代码的灵活性和可维护性。
应用场景:
- 需要创建一组相关或相互依赖的对象:如操作系统中的窗口、按钮和文本框。
- 产品族的概念明确:如不同品牌的家电(冰箱和电视)。
- 客户端不需要知道产品的具体实现:如通过配置文件动态加载具体工厂类。