抽象工厂模式
1.1 分类
(对象)创建型
1.2 提出问题
家具店里有沙发、椅子、茶几等产品。产品有不同风格,如现代、北欧、工业。希望确保客户收到的产品风格统一,并可以方便地添加新产品和风格。
1.3 解决方案
提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
1.4 实现类图
- 抽象产品(Abstract Product):构成系列产品的一组不同但相关的产品声明接口。
- 具体产品(Concrete Product):抽象产品的多种不同类型实现。
- 抽象工厂(Abstract Factory):声明了一组创建各种抽象产品的方法。
- 具体工厂(Concrete Factory):实现抽象工厂的构建方法。
- 客户端(Client):只需通过抽象接口调用工厂和产品对象。
1.5 示例代码
#include <iostream>
// 抽象产品
class Chair {
public:
virtual ~Chair(){}
virtual void sitOn() const = 0;
};
// 具体产品
class ModernChair: public Chair {
public:
virtual ~ModernChair() {}
virtual void sitOn() const override {
std::cout << "可以被坐下的ModernChair\n";
}
};
// 具体产品
class ChineseChair : public Chair {
public:
virtual ~ChineseChair() {}
virtual void sitOn() const override {
std::cout << "可以被坐下的ChineseChair\n";
}
};
// 抽象产品
class Table {
public:
virtual ~Table() {}
virtual void putOn() const = 0;
};
// 具体产品
class ModernTable : public Table {
public:
virtual ~ModernTable() {}
virtual void putOn() const override {
std::cout << "ModernTable可以放东西\n";
}
};
// 具体产品
class ChineseTable : public Table {
public:
virtual ~ChineseTable() {}
virtual void putOn() const override {
std::cout << "ChineseTable可以放东西\n";
}
};
//抽象工厂
class FurnitureFacotry {
public:
virtual Chair* createChair() const = 0;
virtual Table* createTable() const = 0;
};
// 具体工厂
class ModernStyleFactory : public FurnitureFacotry {
public:
virtual Chair* createChair() const override{
return new ModernChair();
}
virtual Table* createTable() const override {
return new ModernTable();
}
};
// 具体工厂
class ChineseStyleFactory : public FurnitureFacotry {
public:
virtual Chair* createChair() const override {
return new ChineseChair();
}
virtual Table* createTable() const override {
return new ChineseTable();
}
};
// 客户端
class Client {
private:
FurnitureFacotry* m_factory;
public:
Client(FurnitureFacotry* factory) {
setFacotry(factory);
}
void buyFurniture() {
Chair* chair = m_factory->createChair();
Table* table = m_factory->createTable();
chair->sitOn();
table->putOn();
delete chair;
delete table;
}
void setFacotry(FurnitureFacotry* factory) {
m_factory = factory;
}
};
int main()
{
ModernStyleFactory modernFactory;
Client client(&modernFactory);
client.buyFurniture();
ChineseStyleFactory chineseFactory;
client.setFacotry(&chineseFactory);
client.buyFurniture();
}
1.6 举个栗子
跨平台 UI 类:使得客户端代码无需与具体 UI 类耦合,就能创建跨平台的 UI 元素,同时确保所创建 的元素与指定的操作系统匹配。
1.7 总结
- 将一个系列的产品族统一到一起创建。 确保系列产品的兼容性。
- 避免客户端和具体产品代码的耦合。
- 单一职责原则。将产品生成代码抽取到同一位置,使得代码易于维护。
- 开闭原则。向应用程序中引入新产品族时,无需修改客户端代码。
- 缺点:在产品族中扩展新的产品需要修改抽象工厂的接口代码。