c++设计模式-抽象工厂
抽象工厂模式
抽象工厂模式
适用情况
例如需要读文件,文件类型都是txt,但是文件有3列的、6列的格式,以后还会有其他格式的;或者设计一个物流类,有水路的、陆路的、以后还会有空航;这些需要很多不同类的情况,以后可能还要添加新的类的情况,一般初期会考虑工厂模式
优缺点
优点:你可以确保同一工厂生成的产品相互匹配。符合单一职责原则和开闭原则
缺点:由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂
与其他模式关系
在许多设计工作的初期都会使用工厂方法模式 (较为简单, 而且可以更方便地通过子类进行定制), 随后演化为使用抽象工厂模式、 原型模式或生成器模式 (更灵活但更加复杂)。
生成器重点关注如何分步生成复杂对象。 抽象工厂专门用于生产一系列相关对象。 抽象工厂会马上返回产品, 生成器则允许你在获取产品前执行一些额外构造步骤。
抽象工厂模式通常基于一组工厂方法, 但你也可以使用原型模式来生成这些类的方法。
当只需对客户端代码隐藏子系统创建对象的方式时, 你可以使用抽象工厂来代替外观模式。
你可以将抽象工厂和桥接模式搭配使用。 如果由桥接定义的抽象只能与特定实现合作, 这一模式搭配就非常有用。 在这种情况下, 抽象工厂可以对这些关系进行封装, 并且对客户端代码隐藏其复杂性。
抽象工厂、 生成器和原型都可以用单例模式来实现。
简易类图
代码实例
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(){};
virtual std::string UsefulFunctionB() const = 0;
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.";
}
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.";
}
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;
}