Abstract Factory(抽象工厂模式)

news2024/10/6 5:55:55

1. 意图

        旨在提供对象创建管理接口,对一系列相关或相互依赖的对象提供统一创建接口,避免在软件中使用各类创建其对象。

2. 适用性

        《Gof 设计模式-可复用面向对象软件的基础》中对此模式的适用性描述如下:

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

3. 实现

  • 简单工厂模式:实现相对简单,类成员函数可以根据不同的参数创建不同的对象,被创建的类对象一般都拥有相同的基类。
class Computer {
public:
  virtual ~Computer (){}
  virtual void Print() = 0;
};

class Memory : public Computer {
  virtual void Print() override { std::cout << "Memory" << std::endl; }
};
class Cpu : public Computer {
  virtual void Print() override { std::cout << "Cpu" << std::endl; }
};
class Screen : public Computer {
  virtual void Print() override { std::cout << "Screen" << std::endl; }
};

class SimpleFactory {
public:
  enum class EnumCreateType { kMemory, kCpu, kScreen };
  Computer *Create(const EnumCreateType &type) {
    switch (type) {
    case EnumCreateType::kMemory:
      return new Memory;
      break;
    case EnumCreateType::kCpu:
      return new Cpu;
      break;
    case EnumCreateType::kScreen:
      return new Screen;
      break;
    default:;
    }
    return nullptr;
  }
};

void Test() {
  SimpleFactory factor;
  Computer *ptr = factor.Create(SimpleFactory::EnumCreateType::kMemory);
  if (ptr) {
    ptr->Print();
    delete ptr;
  }
  ptr = factor.Create(SimpleFactory::EnumCreateType::kCpu);
  if (ptr) {
    ptr->Print();
    delete ptr;
  }
  ptr = factor.Create(SimpleFactory::EnumCreateType::kScreen);
  if (ptr) {
    ptr->Print();
    delete ptr;
  }
}

int main() {
  Test();
  return 0;
}

执行输出

Memory
Cpu
Screen

简单工厂模式模板实现

class Computer {
public:
  virtual ~Computer (){}
  virtual void Print() = 0;
};

class Memory : public Computer {
public:
  Memory(int id) : Computer(), m_id(id) {}
  virtual void Print() override { std::cout << "Memory " << m_id << std::endl; }

private:
  int m_id;
};
class Cpu : public Computer {
public:
  Cpu(int id) : Computer(), m_id(id) {}
  virtual void Print() override { std::cout << "Cpu " << m_id << std::endl; }

private:
  int m_id;
};
class Screen : public Computer {
public:
  Screen(int id) : Computer(), m_id(id) {}
  virtual void Print() override { std::cout << "Screen " << m_id << std::endl; }

private:
  int m_id;
};

class SimpleFactory {
public:
  enum class EnumCreateType { kMemory, kCpu, kScreen };

  template <typename... Args>
  Computer *Create(const EnumCreateType &type, Args &&...args) {
    switch (type) {
    case EnumCreateType::kMemory:
      return new Memory(std::forward<Args>(args)...);
      break;
    case EnumCreateType::kCpu:
      return new Cpu(std::forward<Args>(args)...);
      break;
    case EnumCreateType::kScreen:
      return new Screen(std::forward<Args>(args)...);
      break;
    default:;
    }
    return nullptr;
  }
};

void Test() {
  SimpleFactory factor;
  Computer *ptr = factor.Create(SimpleFactory::EnumCreateType::kMemory, 10);
  if (ptr) {
    ptr->Print();
    delete ptr;
  }
  ptr = factor.Create(SimpleFactory::EnumCreateType::kCpu, 20);
  if (ptr) {
    ptr->Print();
    delete ptr;
  }
  ptr = factor.Create(SimpleFactory::EnumCreateType::kScreen, 30);
  if (ptr) {
    ptr->Print();
    delete ptr;
  }
}

int main() {
  Test();
  return 0;
}

执行输出

Memory 10
Cpu 20
Screen 30
  • 工厂方法模式:使用多个工厂类来创建多种类对象。
class Computer {
public:
  virtual ~Computer() {}
  virtual void Print() = 0;
};

class Memory : public Computer {
  virtual void Print() override { std::cout << "Memory" << std::endl; }
};
class Cpu : public Computer {
  virtual void Print() override { std::cout << "Cpu" << std::endl; }
};
class Screen : public Computer {
  virtual void Print() override { std::cout << "Screen" << std::endl; }
};

class FactoryMethod {
public:
  virtual ~FactoryMethod() {}
  virtual Computer *Create() = 0;
};

class MemoryFactory : public FactoryMethod {
public:
  virtual Computer *Create() override { return new Memory; }
};

class CpuFactory : public FactoryMethod {
public:
  virtual Computer *Create() override { return new Cpu; }
};

class ScreenFactory : public FactoryMethod {
public:
  virtual Computer *Create() override { return new Screen; }
};

void Test() {
  try {
    FactoryMethod *factor = new MemoryFactory;
    Computer *ptr = factor->Create();
    if (ptr) {
      ptr->Print();
      delete ptr;
      delete factor;
    }

    factor = new CpuFactory;
    ptr = factor->Create();
    if (ptr) {
      ptr->Print();
      delete ptr;
      delete factor;
    }

    factor = new ScreenFactory;
    ptr = factor->Create();
    if (ptr) {
      ptr->Print();
      delete ptr;
      delete factor;
    }

  } catch (const std::bad_alloc &err) {
    std::cout << err.what() << std::endl;
  }
}

int main() {
  Test();
  return 0;
}

执行输出

Memory
Cpu
Screen
  • 抽象工厂模式:一个工厂子类不止能创建一种具有相同规则的对象,相对于工厂模式就可以有效的减少创建工厂子类的数量。
#include <iostream>

class Memory {
public:
  virtual ~Memory() {}
  virtual void Print() = 0;
};
class CMemory : public Memory {
public:
  virtual void Print() override { std::cout << "CMemory" << std::endl; }
};
class RMemory : public Memory {
public:
  virtual void Print() override { std::cout << "RMemory" << std::endl; }
};
class FMemory : public Memory {
public:
  virtual void Print() override { std::cout << "FMemory" << std::endl; }
};

class Cpu {
public:
  virtual ~Cpu() {}
  virtual void Print() = 0;
};
class CCpu : public Cpu {
public:
  virtual void Print() override { std::cout << "CCpu" << std::endl; }
};
class RCpu : public Cpu {
public:
  virtual void Print() override { std::cout << "RCpu" << std::endl; }
};
class FCpu : public Cpu {
public:
  virtual void Print() override { std::cout << "FCpu" << std::endl; }
};

class Screen {
public:
  virtual ~Screen() {}
  virtual void Print() = 0;
};
class CScreen : public Screen {
public:
  virtual void Print() override { std::cout << "CScreen" << std::endl; }
};
class RScreen : public Screen {
public:
  virtual void Print() override { std::cout << "RScreen" << std::endl; }
};
class FScreen : public Screen {
public:
  virtual void Print() override { std::cout << "FScreen" << std::endl; }
};

class AbstractFactory {
public:
  virtual ~AbstractFactory() {}

  virtual Memory *CreateMemory() = 0;
  virtual Cpu *CreateCpu() = 0;
  virtual Screen *CreateScreen() = 0;
};

class CFactory : public AbstractFactory {
public:
  virtual Memory *CreateMemory() override { return new CMemory; }
  virtual Cpu *CreateCpu() override { return new CCpu; }
  virtual Screen *CreateScreen() override { return new CScreen; }
};

class RFactory : public AbstractFactory {
public:
  virtual Memory *CreateMemory() override { return new RMemory; }
  virtual Cpu *CreateCpu() override { return new RCpu; }
  virtual Screen *CreateScreen() override { return new RScreen; }
};

class FFactory : public AbstractFactory {
public:
  virtual Memory *CreateMemory() override { return new FMemory; }
  virtual Cpu *CreateCpu() override { return new FCpu; }
  virtual Screen *CreateScreen() override { return new FScreen; }
};

class Computer {
public:
  void Assemble(Memory *memory, Cpu *cpu, Screen *screen) {
    memory->Print();
    cpu->Print();
    screen->Print();
  }
};

void Test() {
  AbstractFactory *factor1 = new CFactory;
  Memory *m1 = factor1->CreateMemory();
  Cpu *c1 = factor1->CreateCpu();
  Screen *s1 = factor1->CreateScreen();

  AbstractFactory *factor2 = new RFactory;
  Memory *m2 = factor2->CreateMemory();
  Cpu *c2 = factor2->CreateCpu();
  Screen *s2 = factor2->CreateScreen();

  AbstractFactory *factor3 = new FFactory;
  Memory *m3 = factor3->CreateMemory();
  Cpu *c3 = factor3->CreateCpu();
  Screen *s3 = factor3->CreateScreen();

  Computer computer;
  computer.Assemble(m1, c2, s3);
  computer.Assemble(m2, c3, s2);
  computer.Assemble(m3, c1, s1);

  delete factor1;
  delete factor2;
  delete factor3;
  delete m1;
  delete m2;
  delete m3;
  delete c1;
  delete c2;
  delete c3;
  delete s1;
  delete s2;
  delete s3;
}

int main() {
  Test();
  return 0;
}

执行输出

CMemory    RCpu    FScreen
RMemory    FCpu    RScreen
FMemory    CCpu    CScreen

4. 优缺点

  • 它分离了具体的类
  • 有利于产品的一致性
  • 难以支持新种类的产品

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

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

相关文章

MySQL--聚合查询、联合查询、子查询、合并查询(上万字超详解!!!)

目录 一、前言二、聚合查询2.1 聚合函数2.1.1 COUNT():统计所有行2.1.2 SUM(列名) 求和2.1.3 AVG()2.1.4 MAX()、MIN() 2.2 GROUP BY子句&#xff08;分组查询&#xff09;2.3 HAVING 三、联合查询3.1表的笛卡儿积3.2内连接3.2.1 例题一3.2.2 例题二 3.3外连接3.3.1 右外连接3.…

【每天学个新注解】Day 16 Lombok注解简解(十五)—@FieldNameConstants

FieldNameConstants 根据属性名生成常量类的常量。 1、如何使用 加在需要根据属性名生成常量的属性上。 2、代码示例 例&#xff1a; FieldNameConstants public class Test {private String iAmAField;private int andSoAmI;FieldNameConstants.Exclude private int asA…

Microsoft AI部门的CEO额备忘录

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

kafka-windows集群部署

kafka-windows集群部署目录 文章目录 kafka-windows集群部署目录前言一、复制出来四个kafka文件夹二、修改集群每个kafka的配置文件四、启动zookeeper&#xff0c;kafka集群 前言 部署本文步骤可以先阅读这一篇博客&#xff0c;这篇是关于单机kafka部署测试的。本文用到的文件…

VUE2常见问题以及解决方案汇总(不断更新中)

解决vue项目中 el-table 的 row-click 事件与行内点击事件冲突&#xff0c;点击事件不生效&#xff08;表格行点击事件和行内元素点击事件冲突&#xff09;需要阻止事件冒泡 问题描述 1.点击列的编辑按钮&#xff0c;会触发按钮本身事件&#xff0c;同时会触发行点击事件 2.点…

自用Proteus(8.15)常用元器件图示和功能介绍(持续更新...)

文章目录 一、 前言二、新建工程&#xff08;以51单片机流水灯为例&#xff09;2.1 打开软件2.2 建立新工程2.3 创建原理图2.4 不创建PCB布版设计2.5 创建成功2.6 添加元器件2.7 原理图放置完成2.8 编写程序&#xff0c;进行仿真2.9 仿真 三、常用元器件图示和功能介绍3.1 元件…

春秋云镜靶场之CVE-2022-28525

1.环境搭建 我们开启环境 可以看到题目提示我们是文件上传漏洞&#xff0c;那么我们就进行测试 2.开启环境 我们开启环境&#xff0c;可以看到是一个登录页面&#xff0c;登录页面:一种是弱口令&#xff0c;一种是自己进行注册&#xff0c;一种是SQL注入&#xff0c;一种是在…

【rCore OS 开源操作系统】Rust 异常处理

【rCore OS 开源操作系统】Rust 异常处理 前言 虽然人还在旅游ing&#xff0c;但是学习不能停止&#xff0c;所以还是写点博客记录下。 对于 Rust 的异常处理&#xff0c;我的感受是&#xff1a;晦涩难懂&#xff0c;繁琐难记。 但是没办法&#xff0c;正如一位故人所说的&…

算法 | 位运算(哈希思想)

位运算 &与两个位都为1时&#xff0c;结果才为1&#xff08;有0为0&#xff09;|或两个位都为0时&#xff0c;结果才为0&#xff08;有1为1&#xff09;^异或两个位相同为0&#xff0c;相异为1~取反0变1&#xff0c;1变0<<左移各二进位全部左移若干位&#xff0c;高…

【FPGA开发】Modelsim如何给信号分组

前面已经发布过了一篇关于 Modelsim 的入门使用教程&#xff0c;针对的基本是只有一个源文件加一个仿真tb文件的情况&#xff0c;而实际的工程应用中&#xff0c;往往是顶层加多个底层的源文件结构&#xff0c;如果不对信号进行一定的分组&#xff0c;就会显得杂乱不堪&#xf…

LSM6DSV16X基于MLC智能笔动作识别(4)----中断获取智能笔状态

LSM6DSV16X基于MLC智能笔动作识别.4--中断获取智能笔状态 概述视频教学样品申请源码下载硬件准备开启INT中断参考驱动程序配置中断主程序演示 概述 LSM6DSV16X 支持通过中断&#xff08;INT&#xff09;输出 MLC&#xff08;机器学习核&#xff09;识别的动作。具体来说&#…

YOLOv8改进线性注意力模块 ICCV2023 FLatten Transformer

1,原理部分 论文地址:2308.00442 (arxiv.org) 在将 Transformer 模型应用于视觉任务时,自我注意的二次计算复杂性一直是一个持续的挑战。另一方面,线性注意力通过精心设计的映射函数近似 Softmax 操作,通过其线性复杂性提供了一种更有效的替代方案。然而,当前的线性注意…

手机sd卡数据被清空怎么恢复原状?高效、可行的恢复策略

在数字化时代&#xff0c;手机SD卡作为我们存储重要数据的“数字仓库”&#xff0c;其安全性与稳定性直接关系到我们日常生活的便捷与信息安全。然而&#xff0c;不慎操作或系统故障导致的SD卡数据清空&#xff0c;常常让人措手不及&#xff0c;焦虑万分。面对这一挑战&#xf…

@antv/x6 导出图片下载,或者导出图片为base64由后端去处理。

1、导出为文件的格式&#xff0c;比如 PNG graph.exportPNG(function (dataURL) {console.log(dataURL);let img document.getElementById(img) as HTMLImageElement;img.src dataURL;},{backgroundColor: #fff,padding: [20, 20, 20, 20],quality: 1,width: graph.options.w…

TIM输入捕获及其应用场景

一&#xff0c;TIM输入捕获介绍&#xff08;IC&#xff08;Input Capture&#xff09;输入捕获&#xff09; 定义&#xff1a;输入捕获模式下&#xff0c;当通道输入引脚出现指定电平跳变&#xff08;如上升沿或下降沿&#xff09;时&#xff0c;当前定时器的计数值&#xff0…

python画图|步进图基本教程

有些时候&#xff0c;画顺滑的图形不能满足表达需求&#xff0c;可能需要使用步进图形来辅助表达。 【1】官网教程 首先我们乖乖进入官网&#xff0c;使用下述链接直达&#xff1a; Step Demo — Matplotlib 3.9.2 documentation 这里有两个图形作为示例&#xff0c;为高效…

第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例

JPA教程 - JPA查询OrderBy两个属性示例 以下代码显示如何按两个属性排序&#xff0c;一个升序&#xff0c;另一个降序。 List l em.createQuery("SELECT e FROM Professor e " "JOIN e.department d ORDER BY d.name, e.name DESC").getResultList();例子…

传感器模块编程实践(二)W5500 SPI转以太网模块简介及驱动源码

文章目录 一.概要二.W5500芯片介绍W5500通讯协议介绍 三.W5500模块介绍四.W5500模块原理图五.W5500以太网模通讯实验六.CubeMX工程源代码下载七.小结 一.概要 我们介绍过单片机的以太网系统一般是由&#xff1a;单片机MACPHYRJ45。有些单片机比如STM32F407VET6芯片内部自带MAC…

如何在Allegro中创建实现可以走线但不能铺铜的区域

第一步&#xff0c;点击Setup-Areas-Shape Keepout&#xff0c;在需要禁止铺铜的区域画好禁示区域&#xff1b; 第二步&#xff0c;画好后&#xff0c;此区域内的动态铺铜会自动避让&#xff0c;而走线不会报错。 参考&#xff1a; Cadence allegro软件如何设置区域为禁止铺铜…

十、kotlin的协程

协程 基本概念定义组成挂起和恢复结构化并发协程构建器作用域构建器挂起函数阻塞与非阻塞runBlocking全局协程像守护线程 Job的生命周期 常用函数延时和等待启动和取消启动取消 暂停 协程启动调度器启动方式启动模式线程上下文继承的定义继承的公式 协程取消与超时取消挂起点取…