设计模式之工厂模式

news/2024/4/28 0:25:46

目录

  • 对象工厂
    • 解决什么问题
    • 使用场景
    • 参与者
    • 优缺点
      • 优点
      • 缺点
    • 实现
    • 代码示例
  • 抽象工厂
    • 参与者
    • 实现
    • 使用场景
    • 协作
    • 优缺点
      • 优点
      • 缺点
    • 代码示例

工厂模式是一种创建新模式。

对象工厂

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类

解决什么问题

面向对象的技术总是企图打破对具象型别的依存性,然而在C++中,对象的生成却将调用者绑死于最底层具象派生类

  • 可能不直接调用new,而是调用某一具有更高级别的对象中的虚函数Create,从而让客户可以通过多态性来改变行为
  • 了解型别信息,但这种信息无法以C++表达,如可能拥有一个字符串包含"Derived",因此需要产生一个Derived的对象

使用场景

  1. 程序库不仅需要操作用户自定义对象,还需要产生他们
  2. 第一种情况产生的对象需要以某种标识符保存其实际型别,通过其标识符再取出具体对象
  3. 当一个类不知道她所必需创建的对象的类的时候
  4. 当一个类希望由它的子类来指定它所创建的对象的时候
  5. 当类将创建对象的职责委托给多个帮助子类种的一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候
  6. 主要用于面向对象程序框架和程序库,以及各种串流处理和对象持久的设计中

参与者

  • Product:定义工厂方法所创建的对象的接口
  • ConcreteProduct:实现Product的接口
  • Creator:声明工厂方法,该方法返回一个Product对象,Creator也可以定义一个工厂方法的缺省实现,返回一个缺省的ConcreteProduct对象
  • ConcreteCreator:重定义工厂方法以返回一个ConcreteProduct实例

优缺点

优点

工厂方法不再将与特定应有有关的类绑定到你的代码中
与多态相比,将型别绑定于实值的动作被推迟的更远,是一种懒初始化的方式

缺点

客户可能仅仅为了创建一个特定的ConcreteFactory对象就不得不创建Creator的子类

实现

  • 主要有两种不同的情况:
    • Creator是一个抽象类并且不提供它所声明的工厂方法的实现
    • Creator是一个具体类而且为工厂方法提供了一个缺省的实现
  • 参数化工厂方法
  • 使用模板以避免创建子类
  • 一个可伸缩的工厂的具体设计:
    • 注册:型别标识符ID和用于产生对象的函数指针/仿函数
      • 型别标识符:用来标识具体对象的型别,由于C++静态型别系统之故,必须先有一个型别标识符,才能生成一个产品;型别标识符的管理由用户负责
      • 对象生产者:函数或仿函数专门用来生成某一类对象。通过函数指针来模塑产品生产者
    • 取消注册
    • 参数化工厂方法:通过型别标识符返回具体对象

代码示例

// 产品基类
class Product {
public:virtual ~Product() {}virtual std::string Operation() const = 0;
};// 具体产品类1
class ConcreteProduct1 : public Product {
public:std::string Operation() const override {return "{Result of the ConcreteProduct1}";}
};
// 具体产品类2
class ConcreteProduct2 : public Product {
public:std::string Operation() const override {return "{Result of the ConcreteProduct2}";}
};// 工厂类
class Creator {
public:virtual ~Creator(){};virtual Product* FactoryMethod() const = 0;std::string SomeOperation() const {Product* product = this->FactoryMethod();std::string result = "Creator: The same creator's code has just worked with " + product->Operation();delete product;return result;}
};// 具体工厂类1
class ConcreteCreator1 : public Creator {
public:Product* FactoryMethod() const override {return new ConcreteProduct1();}
};
// 具体工厂类2
class ConcreteCreator2 : public Creator {
public:Product* FactoryMethod() const override {return new ConcreteProduct2();}
};

抽象工厂

定义:提供一系列相关或相互依赖对象的接口(多态对象),而无需指定他们具体的类。把对象的创建封装在一个类中,这个类的唯一任务就是按需生产各种对象
适用性,它提供了一种方式,可以封装一组具有共同主题的单个工厂,而无需指定它们的具体类。
一个系统要由多个产品系列中的一个来配置时

参与者

  • AbstractFactory:声明一个创建抽象产品对象的操作接口
  • ConcreteFactory:实现创建具体产品对象的操作
  • AbstractProduct:为一类产品对象声明一个接口
  • ConcreteProduct:定义一个将被相应的具体工厂创建的产品对象;实现AbstractProduct接口
    client:仅使用由AbstractFactory和AbstractProduct类声明的接口

实现

将工厂作为单例
创建产品:AbstractFactory仅声明一个创建产品的接口,真正创建产品是由ConcreteProduct子类实现,最通常的办法是为每一个产品定义一个工厂方法。Abstract Factory要求所有对象族系的生成函数都要集中于唯一接口。所以针对待生成物的每一个族系,都必须为这一接口提供一份实作版本——?

使用场景

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

协作

通常在运行时刻创建一个ConcreteFactory类的实例,这一具体的工厂创建具有特定实现的产品对象。为创建不同的产品对象,客户应使用不同的具体工厂

优缺点

优点

分离了具体的类。Abstract Factory模式帮助你控制一个应用创建的对象的类。因为一个工厂封装创建产品对象的责任和过程,它将客户与类的实现分离。
使得易于交换产品系列
有利于产品的一致性

缺点

对型别需求很强烈
难以支持新种类的产品

代码示例

// 抽象产品A和B
class AbstractProductA {
public:virtual ~AbstractProductA() {};virtual std::string UsefulFunctionA() const = 0;
};
class AbstractProductB {
public:virtual ~AbstractProductB() {};virtual std::string UsefulFunctionB() const = 0;
};// 具体产品A1和A2
class ConcreteProductA1 : public AbstractProductA {
public:std::string UsefulFunctionA() const override {return "The result of the product A1.";}
};
class ConcreteProductA2 : public AbstractProductA {
public:std::string UsefulFunctionA() const override {return "The result of the product A2.";}
};// 具体产品B1和B2
class ConcreteProductB1 : public AbstractProductB {
public:std::string UsefulFunctionB() const override {return "The result of the product B1.";}
};
class ConcreteProductB2 : public AbstractProductB {
public:std::string UsefulFunctionB() const override {return "The result of the product B2.";}
};// 抽象工厂
class AbstractFactory {
public:virtual AbstractProductA* CreateProductA() const = 0;virtual AbstractProductB* CreateProductB() const = 0;
};// 具体工厂1
class ConcreteFactory1 : public AbstractFactory {
public:AbstractProductA* CreateProductA() const override {return new ConcreteProductA1();}AbstractProductB* CreateProductB() const override {return new ConcreteProductB1();}
};// 具体工厂2
class ConcreteFactory2 : public AbstractFactory {
public:AbstractProductA* CreateProductA() const override {return new ConcreteProductA2();}AbstractProductB* CreateProductB() const override {return new ConcreteProductB2();}
};

这个例子中,AbstractProductA和AbstractProductB是抽象产品,ConcreteProductA1、ConcreteProductA2、ConcreteProductB1和ConcreteProductB2是具体产品。AbstractFactory是抽象工厂,定义了创建产品的方法,ConcreteFactory1和ConcreteFactory2是具体工厂,实现了创建产品的方法。

使用抽象工厂模式,可以将一组具有共同主题的单个工厂封装起来,使得可以在运行时更换产品系列,而客户端代码不需要进行修改。同时,抽象工厂模式也可以约束客户端使用的产品,确保这些产品是相互配合的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.cpky.cn/p/10795.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

高性能 MySQL 第四版(GPT 重译)(三)

第八章:查询性能优化 在前几章中,我们解释了模式优化和索引,这对于高性能是必要的。但这还不够——您还需要设计良好的查询。如果您的查询不好,即使是设计最佳的模式和索引也不会表现良好。 查询优化、索引优化和模式优化是相辅…

【类脑智能】脑网络通信模型分类及量化指标(附思维导图)

脑网络通信模型分类及量化指标(附思维导图) 参考论文:Brain network communication_ concepts, models and applications 概念 脑网络通信模型是一种使用图论和网络科学概念来描述和量化大脑结构中信息传递的模型。这种模型可以帮助研究人员理解神经信号在大脑内…

智能合约语言(eDSL)—— 使用rust实现eDSL的原理

为理解rust变成eDSL的实现原理,我们需要简单了解元编程与宏的概念,元编程被描述成一种计算机程序可以将代码看待成数据的能力,使用元编程技术编写的程序能够像普通程序在运行时更新、替换变量那样操作更新、替换代码。宏在 Rust 语言中是一种功能&#x…

基于数据库的全文检索实现

对于内容摘要&#xff0c;信件内容进行全文检索 基于SpringBoot 2.5.6Postgresqljpahibernate实现 依赖 <spring-boot.version>2.5.6</spring-boot.version> <hibernate-types-52.version>2.14.0</hibernate-types-52.version><dependency><…

数字多空策略(实盘+回测+数据)

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

Python之Web开发中级教程----ubuntu安装MySQL

Python之Web开发中级教程----ubuntu安装MySQL 进入/opt目录 cd /opt 更新软件源 sudo apt-get upgrade sudo apt-get update 3、安装Mysql server sudo apt-get install mysql-server 4、启动Mysql service mysql start 5、确认Mysql的状态 service mysql status 6、安全设…