抽象工厂模式 (Abstract Factory Pattern)

抽象工厂模式 (Abstract Factory Pattern) 是一种创建型设计模式,它提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

一、基础

1. 意图

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

2. 适用场景

  • 当一个系统要独立于它的产品的创建、组合和表示时。
  • 当一个系统要由多个产品系列中的一个来配置时。
  • 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
  • 当你提供一个产品类库,而只想显示它们的接口而不是实现时。

3. 结构

  • 抽象产品族(AbstractProductFamily) :定义了一系列相关产品的抽象接口,这些产品之间存在某种关联或依赖关系。
  • 具体产品(ConcreteProduct) :实现了抽象产品族接口的具体产品类。每个具体产品类对应抽象产品族中的一个产品。
  • 抽象工厂(AbstractFactory) :声明了创建抽象产品族中各个产品的抽象方法。抽象工厂类负责定义创建一系列相关产品的接口,这些产品构成一个产品族。
  • 具体工厂(ConcreteFactory) :实现了抽象工厂中声明的创建各个产品的方法,用于创建具体的产品对象。每个具体工厂类负责创建特定产品族中的所有产品。

二、进阶

1. 抽象工厂模式的优点

  • 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。
  • 当一个产品族中的多个对象被设计成一起工作时,抽象工厂模式能够保证客户端始终只使用同一个产品族中的对象。
  • 增加新的具体工厂和产品族很方便,无需修改已有系统,符合"开闭原则"。

2. 抽象工厂模式的缺点

  • 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,违背了"开闭原则"。

3. 抽象工厂模式的应用

  • 抽象工厂模式广泛应用于各种框架和库中,例如 Spring 框架、Hibernate 框架等。
  • 抽象工厂模式也可以用于开发各种应用程序,例如游戏、图形用户界面等。

三、关键技术

1. 抽象工厂模式的实现

  • 抽象工厂模式可以通过接口或抽象类来实现。
  • 抽象工厂模式可以通过静态方法或实例方法来实现。

2. 抽象工厂模式的扩展

  • 抽象工厂模式可以与其他设计模式结合使用,例如单例模式、原型模式等。
  • 抽象工厂模式可以扩展为工厂方法模式,从而支持创建单一产品对象。

四、易错点

1. 抽象工厂模式的滥用

  • 抽象工厂模式不应该被滥用,只有在需要创建一系列相关或相互依赖的对象时才应该使用抽象工厂模式。

2. 抽象工厂模式的性能问题

  • 抽象工厂模式可能会降低代码的性能,因为每次创建对象时都需要调用工厂方法。

五、核心代码

5.1 抽象工厂模式的简单实现

cpp 复制代码
// AbstractProductA
class AbstractProductA {
public:
    virtual void use() = 0;
};

// ConcreteProductA1
class ConcreteProductA1 : public AbstractProductA {
public:
    void use() override {
        std::cout << "Using ConcreteProductA1" << std::endl;
    }
};

// ConcreteProductA2
class ConcreteProductA2 : public AbstractProductA {
public:
    void use() override {
        std::cout << "Using ConcreteProductA2" << std::endl;
    }
};

// AbstractProductB
class AbstractProductB {
public:
    virtual void eat() = 0;
};

// ConcreteProductB1
class ConcreteProductB1 : public AbstractProductB {
public:
    void eat() override {
        std::cout << "Eating ConcreteProductB1" << std::endl;
    }
};

// ConcreteProductB2
class ConcreteProductB2 : public AbstractProductB {
public:
    void eat() override {
        std::cout << "Eating ConcreteProductB2" << std::endl;
    }
};

// AbstractFactory
class AbstractFactory {
public:
    virtual AbstractProductA* createProductA() = 0;
    virtual AbstractProductB* createProductB() = 0;
};

// ConcreteFactory1
class ConcreteFactory1 : public AbstractFactory {
public:
    AbstractProductA* createProductA() override {
        return new ConcreteProductA1();
    }

    AbstractProductB* createProductB() override {
        return new ConcreteProductB1();
    }
};

// ConcreteFactory2
class ConcreteFactory2 : public AbstractFactory {
public:
    AbstractProductA* createProductA() override {
        return new ConcreteProductA2();
    }

    AbstractProductB* createProductB() override {
        return new ConcreteProductB2();
    }
};

// Client
int main() {
    AbstractFactory* factory = new ConcreteFactory1();
    AbstractProductA* productA = factory->createProductA();
    AbstractProductB* productB = factory->createProductB();

    productA->use();
    productB->eat();

    delete factory;
    delete productA;
    delete productB;

    factory = new ConcreteFactory2();
    productA = factory->createProductA();
    productB = factory->createProductB();

    productA->use();
    productB->eat();

    delete factory;
    delete productA;
    delete productB;

    return 0;
}

5.2 抽象工厂模式的扩展实现

cpp 复制代码
// AbstractProductA
class AbstractProductA {
public:
    virtual void use() = 0;
};

// ConcreteProductA1
class ConcreteProductA1 : public AbstractProductA {
public:
    void use() override {
        std::cout << "Using ConcreteProductA1" << std::endl;
    }
};

// ConcreteProductA2
class ConcreteProductA2 : public AbstractProductA {
public:
    void use() override {
        std::cout << "Using ConcreteProductA2" << std::endl;
    }
};

// AbstractProductB
class AbstractProductB {
public:
    virtual void eat() = 0;
};

// ConcreteProductB1
class ConcreteProductB1 : public AbstractProductB {
public:
    void eat() override {
        std::cout << "Eating ConcreteProductB1" << std::endl;
    }
};

// ConcreteProductB2
class ConcreteProductB2 : public AbstractProductB {
public:
    void eat() override {
        std::cout << "Eating ConcreteProductB2" << std::endl;
    }
};

// AbstractFactory
class AbstractFactory {
public:
    virtual AbstractProductA* createProductA() = 0;
    virtual AbstractProductB* createProductB() = 0;
};

// ConcreteFactory1
class ConcreteFactory1 : public AbstractFactory {
public:
    AbstractProductA* createProductA() override {
        return new ConcreteProductA1();
    }

    AbstractProductB* createProductB() override {
        return new ConcreteProductB1();
    }
};

// ConcreteFactory2
class ConcreteFactory2 : public AbstractFactory {
public:
    AbstractProductA* createProductA() override {
        return new ConcreteProductA2();
    }

    AbstractProductB* createProductB() override {
        return new ConcreteProductB2();
    }
};

// Client
int main() {
    AbstractFactory* factory = new ConcreteFactory1();
    AbstractProductA* productA = factory->createProductA();
    AbstractProductB* productB = factory->createProductB();

    productA->use();
    productB->eat();

    delete factory;
    delete productA;
    delete productB;

    factory = new ConcreteFactory2();
    productA = factory->createProductA();
    productB = factory->createProductB();

    productA->use();
    productB->eat();

    delete factory;
    delete productA;
    delete productB;

    return 0;
}

六、总结

抽象工厂模式通过将对象的创建和使用进一步分离,为创建一系列相关或相互依赖的对象提供了一种优雅的解决方案。它在提高系统的可扩展性和可维护性方面具有显著优势,但同时也增加了系统的复杂性。在实际开发中,需要根据具体的业务需求和系统架构来权衡是否使用抽象工厂模式。如果系统中存在多个产品族,并且产品之间存在复杂的依赖关系,那么抽象工厂模式是一个很好的选择。

相关推荐
汉克老师36 分钟前
GESP6级C++考试语法知识(十七、数据结构(三、认识队列 Queue))
数据结构·c++·队列·gesp6级·gesp六级·数组模拟队列
j_xxx404_2 小时前
Linux进程信号捕捉与操作系统运行本质深度解析
linux·运维·服务器·开发语言·c++·人工智能·ai
魔法阵维护师3 小时前
从零开发游戏需要学习的c#模块,第十章(设计模式入门)
学习·游戏·设计模式·c#
用户356302904873 小时前
【设计模式】组合模式——树形结构的统一处理
设计模式
vx-程序开发3 小时前
基于机器学习的动漫可视化系统的设计与实现-计算机毕业设计源码08339
java·c++·spring boot·python·spring·django·php
啊董dong4 小时前
noi-2026年5月12号小测验
数据结构·c++·算法
咩咦5 小时前
C++学习笔记24:构造函数初始化列表
c++·学习笔记·类和对象·构造函数·初始化列表·const引用
计算机安禾5 小时前
【c++面向对象编程】第43篇:可变参数模板(C++11):优雅处理不定长参数
java·开发语言·c++
10岁的博客5 小时前
C++ 进制转换:通用 a 进制转 b 进制(2-36进制)题解
开发语言·c++
小贾要学习6 小时前
【Linux】基于自定义TCP协议的日期计算器
linux·网络·c++·网络协议·tcp/ip