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

设计模式学习(二)工厂模式——工厂方法模式

设计模式学习(二)工厂模式——工厂方法模式

  • 前言
  • 工厂方法模式
    • 简介
    • 示例
    • 优点
    • 缺点
    • 使用场景

前言

前一篇文章介绍了简单工厂模式,提到了简单工厂模式的缺点(违反开闭原则,扩展困难),本文要介绍的工厂方法模式在一定程度上弥补了简单工厂模式的缺点。

工厂方法模式

简介

工厂方法模式是创建型设计模式之一,它在抽象工厂类中声明创建对象的接口,在具体工厂类中实现具体的实例化过程。这个模式的核心思想是将对象的实例化延迟到子类中进行,从而使得父类通过其子类来指定创建哪个对象,实现了类的实例化操作的封装和数据的封装。

这样的话,当要添加一个具体产品时,我们不会修改原有的工厂类(不违反开闭原则),而是新创建一个关联于具体产品的具体工厂类(易扩展)。

示例

抽象相机类:CameraDevice
具体相机类:BaslerCameraDevice,SickCameraDevice,HuarayCameraDevice

抽象工厂类:CameraDeviceFactory
具体工厂类:BaslerCameraFactory,SickCameraFactory,HuarayCameraFactory

UML类图如下:
在这里插入图片描述

代码如下:

// 抽象产品类
class CameraDevice
{
public:CameraDevice() = default;virtual ~CameraDevice() = 0;virtual bool Init(){};virtual bool OpenDevice() = 0;
};class BaslerCameraDevice : public CameraDevice
{
public:~BaslerCameraDevice() override;bool Init() override{};bool OpenDevice() override{};
};class HuarayCameraDevice : public CameraDevice
{
public:~HuarayCameraDevice() override{};bool Init() override{};bool OpenDevice() override{};
};class SickCameraDevice : public CameraDevice
{
public:~SickCameraDevice() override{};bool Init() override{};bool OpenDevice() override{};
};// 抽象工厂类
class CameraDeviceFactory 
{
public:virtual std::shared_ptr<CameraDevice> CreateCamera() = 0;
};// 具体工厂类
class BaslerCameraFactory : public CameraDeviceFactory 
{
public:std::shared_ptr<CameraDevice> CreateCamera() override {return std::make_shared<BaslerCameraDevice>();}
};class HuarayCameraFactory : public CameraDeviceFactory 
{
public:std::shared_ptr<CameraDevice> CreateCamera() override {return std::make_shared<HuarayCameraDevice>();}
};class SickCameraFactory : public CameraDeviceFactory 
{
public:std::shared_ptr<CameraDevice> CreateCamera() override {return std::make_shared<SickCameraDevice>();}
};int main() 
{std::shared_ptr<CameraDeviceFactory> factory = std::make_shared<BaslerCameraFactory>();std::shared_ptr<CameraDevice> camera = factory->CreateCamera();camera->Init();camera->OpenDevice();return 0;
}

优点

  • 解耦:工厂方法模式可以减少客户代码与具体类之间的耦合。客户端在使用的时候只需知道接口,而不是具体类。这样可以更容易地扩展或修改创建逻辑,而无需修改现有客户代码。
  • 符合开闭原则:工厂方法模式允许系统在不修改现有代码的情况下引入新的类型。满足对扩展开放,对修改封闭的原则。
  • 单一职责原则:工厂方法模式中,创建对象的逻辑被封装在一个工厂类中,这符合单一职责原则。这让代码更加清晰,维护也更简单。

缺点

  • 代码复杂:工厂方法模式为每种产品类型提供一个单独的工厂类。这意味着每增加一个新的产品类别,就需要增加一个新的具体工厂类。这会导致类的数量迅速增加,从而增加了代码的复杂性
  • 代码冗余:如果具体工厂类之间的创建逻辑相似,这可能会导致代码冗余。虽然每个工厂类只负责创建一个具体产品,但这些工厂类的创建逻辑可能高度相似,不能有效地重用代码。

使用场景

  • 产品类别经常变化:一个系统会频繁添加或修改产品的创建,而每种产品的创建又有不同的复杂配置和依赖时,工厂方法可以将具体产品的创建逻辑封装在各自的工厂类中,从而简化客户端代码。

相关文章:

  • 一文看懂人工智能、机器学习、深度学习是什么、有什么区别!
  • 618必抢清单:内存升级国货更强,DDR5劲爆大白菜
  • 云和运维(SRE)的半生缘-深读实证02
  • PCA 在图像分析上的应用
  • linux-touch指令
  • 重学java 71.网络编程
  • 【AI开发】CRAG、Self-RAG、Adaptive-RAG
  • 服务器----阿里云服务器重启或关机,远程连接进不去,个人博客无法打开
  • Unity API学习之资源的动态加载
  • 作者推荐 | 探索分析从起源到现今的巅峰之旅(MySQL存储模型)
  • java如何分割字符串
  • 04 远程访问及控制
  • 如何定义和衡量一个产品的成功?
  • 复旦发布开源版本的EMO,只需输入一段音频和一张照片就可以让人物开始说话。
  • 50etf期权交易规则杠杆怎么计算?
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • If…else
  • Java程序员幽默爆笑锦集
  • JS+CSS实现数字滚动
  • leetcode98. Validate Binary Search Tree
  • ReactNativeweexDeviceOne对比
  • Spark RDD学习: aggregate函数
  • vue.js框架原理浅析
  • 大主子表关联的性能优化方法
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 目录与文件属性:编写ls
  • 前端面试之CSS3新特性
  • 使用权重正则化较少模型过拟合
  • 微信小程序设置上一页数据
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​Java并发新构件之Exchanger
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #{}和${}的区别?
  • (11)MSP430F5529 定时器B
  • (30)数组元素和与数字和的绝对差
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (二十三)Flask之高频面试点
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (含答案)C++笔试题你可以答对多少?
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (三)模仿学习-Action数据的模仿
  • (转) Android中ViewStub组件使用
  • (转)IOS中获取各种文件的目录路径的方法
  • .NET 8.0 发布到 IIS
  • .NET Core引入性能分析引导优化
  • .Net Remoting(分离服务程序实现) - Part.3
  • .NET/C# 的字符串暂存池
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .net操作Excel出错解决
  • /etc/sudoer文件配置简析
  • /etc/X11/xorg.conf 文件被误改后进不了图形化界面