当前位置: 首页 > article >正文

【C++设计模式】(四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式

文章目录

  • (四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式
    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式

(四)创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式

在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。工厂模式的动机在于通过一个专门的工厂类来封装对象的创建过程,以解耦对象的使用和创建,隐藏复杂的对象实例化逻辑,从而提高代码的灵活性和可维护性。通过工厂模式,客户端代码只需与工厂接口或抽象类交互,而不必直接与具体类耦合,这使得系统更易于扩展和修改。

工厂模式可以分为简单工厂模式,工厂方法模式和抽象工厂模式。

简单工厂模式

简单工厂模式(不属于GoF的23种设计模式):工厂类根据输入的参数决定创建哪一种产品类的实例。

#include <iostream>
#include <string>

// 抽象产品类
class Product {
public:
    virtual void operation() = 0;
    virtual ~Product() {}  // 虚析构函数,确保正确释放资源
};

// 具体产品类 A
class ConcreteProductA : public Product {
public:
    void operation() override {
        std::cout << "ConcreteProductA operation." << std::endl;
    }
};

// 具体产品类 B
class ConcreteProductB : public Product {
public:
    void operation() override {
        std::cout << "ConcreteProductB operation." << std::endl;
    }
};

// 简单工厂类
class SimpleFactory {
public:
    // 静态工厂方法,根据传入的字符串类型创建具体的产品对象
    static Product* createProduct(const std::string& type) {
        if (type == "A") {
            return new ConcreteProductA();  // 创建并返回 ConcreteProductA 对象
        } else if (type == "B") {
            return new ConcreteProductB();  // 创建并返回 ConcreteProductB 对象
        } else {
            return nullptr;        // 如果传入的类型无效,返回空指针
        }
    }
};


int main() {
    // 使用简单工厂创建产品 A
    Product* productA = SimpleFactory::createProduct("A");
    if (productA) {
        productA->operation();
        delete productA;
    }

    // 使用简单工厂创建产品 B
    Product* productB = SimpleFactory::createProduct("B");
    if (productB) {
        productB->operation();
        delete productB;
    }

    return 0;
}

以上代码通过引入一个工厂类SimpleFactory ,将产品对象AB 的创建过程封装在工厂方法中,从而实现对象创建与使用的分离。客户端只需要通过工厂来获取对象,无需了解对象的创建细节。

工厂方法模式

简单工厂违反了开闭原则(对扩展开放,对修改关闭),因为每当需要引入新产品时,都需要修改工厂类。为了避免这个问题,工厂方法模式定义一个抽象工厂类,通过继承得到可以创建不同产品的工厂。

示例

#include <iostream>
#include <string>

// 抽象产品类
class Product {
public:
    virtual void operation() = 0;
    virtual ~Product() {}  // 虚析构函数,确保正确释放资源
};

// 具体产品类 A
class ConcreteProductA : public Product {
public:
    void operation() override {
        std::cout << "ConcreteProductA operation." << std::endl;
    }
};

// 具体产品类 B
class ConcreteProductB : public Product {
public:
    void operation() override {
        std::cout << "ConcreteProductB operation." << std::endl;
    }
};

// 抽象工厂类
class Factory {
public:
    virtual Product* createProduct() = 0;
    virtual ~Factory() {}  // 虚析构函数,确保正确释放资源
};

// 具体工厂类 A,创建 ConcreteProductA
class ConcreteFactoryA : public Factory {
public:
    Product* createProduct() override {
        return new ConcreteProductA();
    }
};

// 具体工厂类 B,创建 ConcreteProductB
class ConcreteFactoryB : public Factory {
public:
    Product* createProduct() override {
        return new ConcreteProductB();
    }
};


int main() {
    // 使用具体工厂类 A 创建产品 A
    Factory* factoryA = new ConcreteFactoryA();
    Product* productA = factoryA->createProduct();
    productA->operation();
    delete productA;
    delete factoryA;

    // 使用具体工厂类 B 创建产品 B
    Factory* factoryB = new ConcreteFactoryB();
    Product* productB = factoryB->createProduct();
    productB->operation();
    delete productB;
    delete factoryB;

    return 0;
}

这段代码通过定义一个抽象工厂类Factory来声明创建产品对象的接口,具体的产品创建由具体工厂类(ConcreteFactoryAConcreteFactoryB)来实现。工厂方法模式能在不修改已有代码的情况下,通过增加新的工厂类来创建新的产品类型,实现对开闭原则的遵循。

抽象工厂模式

抽象工厂模式的主要是为了解决在不需要指定具体类的情况下,创建一组相关或依赖对象 (产品族)的需求。它通过提供一个接口来创建一系列相关或依赖对象的工厂,使得客户端可以在不指定具体实现类的情况下,创建产品族中的产品。

#include <iostream>
#include <string>

// 抽象产品 A 类
class ProductA {
public:
    virtual void operation() = 0;
    virtual ~ProductA() {}  // 虚析构函数,确保正确释放资源
};

// 具体产品 A1
class ConcreteProductA1 : public ProductA {
public:
    void operation() override {
        std::cout << "ConcreteProductA1 operation." << std::endl;
    }
};

// 具体产品 A2
class ConcreteProductA2 : public ProductA {
public:
    void operation() override {
        std::cout << "ConcreteProductA2 operation." << std::endl;
    }
};


// 抽象产品 B 类
class ProductB {
public:
    virtual void operation() = 0;
    virtual ~ProductB() {} 
};

// 具体产品 B1
class ConcreteProductB1 : public ProductB {
public:
    void operation() override {
        std::cout << "ConcreteProductB1 operation." << std::endl;
    }
};

// 具体产品 B2
class ConcreteProductB2 : public ProductB {
public:
    void operation() override {
        std::cout << "ConcreteProductB2 operation." << std::endl;
    }
};

// 抽象工厂类
class AbstractFactory {
public:
    virtual ProductA* createProductA() = 0;
    virtual ProductB* createProductB() = 0;
    virtual ~AbstractFactory() {} 
};

// 具体工厂 1,创建产品 A1 和 B1
class ConcreteFactory1 : public AbstractFactory {
public:
    ProductA* createProductA() override {
        return new ConcreteProductA1();
    }
    
    ProductB* createProductB() override {
        return new ConcreteProductB1();
    }
};

// 具体工厂 2,创建产品 A2 和 B2
class ConcreteFactory2 : public AbstractFactory {
public:
    ProductA* createProductA() override {
        return new ConcreteProductA2();
    }
    
    ProductB* createProductB() override {
        return new ConcreteProductB2();
    }
};


int main() {
    // 使用具体工厂 1 创建产品 A1 和 B1
    AbstractFactory* factory1 = new ConcreteFactory1();
    ProductA* productA1 = factory1->createProductA();
    ProductB* productB1 = factory1->createProductB();
    
    productA1->operation();
    productB1->operation();
    
    delete productA1;
    delete productB1;
    delete factory1;

    // 使用具体工厂 2 创建产品 A2 和 B2
    AbstractFactory* factory2 = new ConcreteFactory2();
    ProductA* productA2 = factory2->createProductA();
    ProductB* productB2 = factory2->createProductB();
    
    productA2->operation();
    productB2->operation();
    
    delete productA2;
    delete productB2;
    delete factory2;

    return 0;
}

http://www.kler.cn/news/330311.html

相关文章:

  • 阿里云 SAE Web:百毫秒高弹性的实时事件中心的架构和挑战
  • 【算法篇】二叉树类(3)(笔记)
  • Redis: Sentinel节点管理,故障迁移一致性以及TILT模式
  • 计算机网络-系分(5)
  • 2、Spring Boot 3.x 集成 Feign
  • javascript手写实现instanceof函数 介绍判断数组的方法
  • 网站开发基础:HTML、CSS
  • 四、网络层(下)
  • 《 Spring Boot实战:优雅构建责任链模式投诉处理业务》
  • 【Redis 源码】6AOF持久化
  • Linux_kernel字符设备驱动12
  • 云计算SLA响应时间的matlab模拟与仿真
  • Golang | Leetcode Golang题解之第446题等差数列划分II-子序列
  • C++学习笔记----8、掌握类与对象(二)---- 成员函数的更多知识(3)
  • 【数一线性代数】021入门
  • 代码工艺:Spring Boot 防御式编程实践
  • JavaScript Map全解:从基础到高级应用
  • jackson对于对象序列化的时候默认空值和手动传入的null的不同处理
  • 模拟斗地主发扑克的编程
  • Vue.js组件开发教程