一、意图
提供一个接口一创建一系列相关或相互依赖的对象,而无需指定它们具体的类。
二、UML

三、问题
假设我们开发一些列产品,例如:椅子Chair、沙发Sofa和咖啡桌CoffeTable。现在我们有多种产品的变体:如现代Modern、维多利亚Vectorian、装饰风艺术ArtDeco等风格来生成与椅子、沙发和咖啡桌。

为了确保产品生成的风格一致,同时减少增添新产品或新风格时的代码修改量,我们引入抽象工厂模式。
四、解决方案
首先,抽象工厂模式建议为系列中的每件产品明确声明接口(例如椅子、 沙发或咖啡桌)。然后,确保所有产品变体都继承这些接口。例如,所有风格的椅子都实现椅子接口;所有风格的咖啡桌都实现咖啡桌接口,以此类推。

接下来,我们需要声明抽象工厂——包含系列中所有产品构造方法的接口。例如 createChair创建椅子 、createSofa创建沙发和createCoffeeTable创建咖啡桌。这些方法必须返回抽象产品类型,即我们之前抽取的那些接口:椅子,沙发和咖啡桌等等。

那么该如何处理产品变体呢?对于系列产品的每个变体,我们都将基于抽象工厂接口创建不同的工厂类。每个工厂类都只能返回特定类别的产品,例如,现代家具工厂ModernFurnitureFactory只能创建现代椅子ModernChair、现代沙发ModernSofa和现代咖啡桌ModernCoffeeTable对象。
客户端代码可以通过相应的抽象接口调用工厂和产品类。 你无需修改实际客户端代码, 就能更改传递给客户端的工厂类, 也能更改客户端代码接收的产品变体。

假设客户端想要工厂创建一把椅子。客户端无需了解工厂类,也不用管工厂类创建出的椅子类型。无论是现代风格,还是维多利亚风格的椅子,对于客户端来说没有分别,它只需调用抽象椅子接口就可以了。 这样一来,客户端只需知道椅子以某种方式实现了sitOn坐下方法就足够了。此外,无论工厂返回的是何种椅子变体,它都会和由同一工厂对象创建的沙发或咖啡桌风格一致。
最后一点说明: 如果客户端仅接触抽象接口, 那么谁来创建实际的工厂对象呢? 一般情况下, 应用程序会在初始化阶段创建具体工厂对象。 而在此之前, 应用程序必须根据配置文件或环境设定选择工厂类别。
五、实例
#include <iostream> #include <map> #include <memory> /* ==============================*/ /* ===== Product 00 : Chair =====*/ /* ==============================*/ class AbstractChair { public: virtual ~AbstractChair() {} virtual std::string GetChairName() const = 0; }; class ArtDecoChair : public AbstractChair { public: std::string GetChairName() const override { return "Art Deco Chair"; } }; class VictorianChair : public AbstractChair { public: std::string GetChairName() const override { return "Victorian Chair"; } }; class ModernChair : public AbstractChair { public: std::string GetChairName() const override { return "Modern Chair"; } }; /* =============================*/ /* ===== Product 02 : Sofa =====*/ /* =============================*/ class AbstractSofa { public: virtual ~AbstractSofa() {} virtual std::string GetSofaName() const = 0; }; class ArtDecoSofa : public AbstractSofa { std::string GetSofaName() const override { return "Art Deco Sofa"; } }; class VictorianSofa : public AbstractSofa { std::string GetSofaName() const override { return "Victorian Sofa"; } }; class ModernSofa : public AbstractSofa { std::string GetSofaName() const override { return "Modern Sofa"; } }; /* ===================*/ /* ===== Factory =====*/ /* ===================*/ class AbstractFactory { public: virtual AbstractChair* CreateChair() const = 0; virtual AbstractSofa* CreateSofa() const = 0; }; class ArtDecoFactory : public AbstractFactory { public: AbstractChair* CreateChair() const override { return new ArtDecoChair(); } AbstractSofa* CreateSofa() const override { return new ArtDecoSofa(); } }; class VictorianFactory : public AbstractFactory { public: AbstractChair* CreateChair() const override { return new VictorianChair(); } AbstractSofa* CreateSofa() const override { return new VictorianSofa(); } }; class ModernFactory : public AbstractFactory { AbstractChair* CreateChair() const override { return new ModernChair(); } AbstractSofa* CreateSofa() const override { return new ModernSofa(); } }; void Cilent_ShowProduct(const AbstractFactory& p_factory) { const AbstractChair* chair = p_factory.CreateChair(); const AbstractSofa* sofa = p_factory.CreateSofa(); std::cout << chair->GetChairName() << std::endl; std::cout << sofa->GetSofaName() << std::endl; delete chair; delete sofa; } int main() { std::cout << "now is Art Deco Factory" << std::endl; const ArtDecoFactory* artdecoFactory = new ArtDecoFactory(); Cilent_ShowProduct(*artdecoFactory); return 0; }
Comments | NOTHING