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

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

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

前言

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

工厂方法模式

简介

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

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

示例

抽象相机类: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;
}

优点

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

缺点

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

使用场景

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

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

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

相关文章

Hadoop 2.0:主流开源云架构(四)

目录 五、Hadoop 2.0访问接口&#xff08;一&#xff09;访问接口综述&#xff08;二&#xff09;浏览器接口&#xff08;三&#xff09;命令行接口 六、Hadoop 2.0编程接口&#xff08;一&#xff09;HDFS编程&#xff08;二&#xff09;Yarn编程 五、Hadoop 2.0访问接口 &am…

java打印helloworld

源代码 public class Function1 {public static void main(String[] args) {System.out.println("hello world");}} 打印结果

为什么说Python 是胶水语言?

​ "Python 是胶水语言"这一说法是指它很擅长将不同的程序或代码库连接在一起&#xff0c;能够让来自不同编程语言或框架的组件无缝协作。Python 具有丰富的库和简单的语法&#xff0c;使得它可以轻松调用其他语言编写的程序或使用不同技术栈的模块。 ​ 以下是几个…

C学习自学笔记-会陆续完善对应章节编程经典例子

C学习笔记 0>C语言概述 为什么学习C语言 1&#xff09;C的起源和发展------了解即可 B语言、C语言、C语言的产生地&#xff1a;都出自 美国贝尔实验室 2&#xff09;C的特点 优点&#xff1a;代码量小、速度快、功能强大 缺点&#xff1a;危险性高、开发周期长、可移植性…

MATLAB直方图中bin中心与bin边界之间的转换

要将 bin 中心转换为 bin 边界&#xff0c;请计算 centers 中各连续值之间的中点。 d diff(centers)/2; edges [centers(1)-d(1), centers(1:end-1)d, centers(end)d(end)];要将 bin 边界转换为bin 中心 bincenters binedges(1:end-1)diff(binedges)/2;

每日一练——用队列实现栈

225. 用队列实现栈 - 力扣&#xff08;LeetCode&#xff09; Queue.h #pragma once #include<stdlib.h> #include<assert.h> #include<stdbool.h>typedef int QDataType;typedef struct QNode {QDataType data;struct QNode* next; } QNode;typedef struct …

【办公类-04-03】华为助手导出照片视频分类(根据图片、视频的文件名日期分类导出)

背景需求&#xff1a; 用华为手机助手导出的照片视频&#xff0c;只能将jpg照片&#xff08;exifread读取图片的exif拍摄日期&#xff0c;Png、JPEG、mp4都无法识别到exif信息&#xff09; 【办公类-04-02】华为助手导出照片&#xff08;jpg&#xff09;读取拍摄时间分类导出…

LeetCode | 709.转换成小写字母

这道题可以用api也可以自己实现&#xff0c;都不难&#xff0c;大小字母之前相差了32&#xff0c;检查到大写字母时加上32即可 class Solution(object):def toLowerCase(self, s):""":type s: str:rtype: str"""return s.lower()class Solution…

试论地产需求政策的有效性边界

分析师通过对传统框架因子的分析和美日地产的回顾&#xff0c;指出收入政策将成为核心&#xff0c;测算认为地方收储面积约0.5-1.1亿平、收储资金0.8-1.9万亿元&#xff0c;70城二手房价降幅收窄至[-4.5%&#xff0c;-1.6%]。 事件&#xff1a;2024年5月17日&#xff0c;央行印…

git 快速将当前目录添加仓储

一、进入目录 git init git add . git commit -m "init" git remote add origin http://192.168.31.104/root/AutoBuildDemo.git 二、登录gitlab&#xff0c;创建项目AutoBuildDemo 最后执行&#xff1a; git push -u origin master

Github 2024-06-12 C开源项目日报 Top10

根据Github Trendings的统计,今日(2024-06-12统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10PHP项目1PLpgSQL项目1C++项目1Ventoy: 100%开源的可启动USB解决方案 创建周期:1534 天开发语言:C协议类型:GNU General Public Licen…

2024年7款硬盘恢复软件:即刻恢复硬盘删除的文件!

当文件被删除后&#xff0c;它并不是立即从硬盘中消失&#xff0c;而是被标记为“已删除”&#xff0c;等待垃圾回收处理。因此&#xff0c;在文件被删除后&#xff0c;有几种方法可以尝试恢复删除的数据。 以下是7款常用的数据恢复软件&#xff0c;以及它们的详细介绍&#xf…

单片机与DHT11温湿度检测设计

本次设计是采用STC89C54单片机加上低成本的温湿度模块DHT11构成的温湿度检测系统。设计主要由硬件与软件两部分设计构成。硬件方面包括单片机STC89C54、温湿度模块DHT11、显示模块LCD1602、电池电源、I2C存储器以及控制按键等5个部分。此系统完全基于单片机最小系统并进行一定的…

【C++ | 静态成员】类的 静态(static)数据成员、静态(static)成员函数 详解及例子代码

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-06-16 0…

Electron+vite+vuetify项目搭建

最近想用Electron来进行跨平台的桌面应用开发。同时想用vuetify作为组件&#xff0c;于是想搭建一个这样的开发环境。其中踩了不少坑&#xff0c;总是会出现各种的编译错误和问题&#xff0c;依赖的各种问题&#xff0c;搞了好久最终环境终于弄好可正常开发了。这里分享下快速搭…

践行国产化替代,优刻得私有云勇当先锋

编辑&#xff1a;阿冒 设计&#xff1a;沐由 阳泉&#xff0c;十万火急&#xff01; 位于太行山西麓的山西省阳泉市&#xff0c;是一座历史悠久、底蕴深厚、资源丰富的名城&#xff0c;拥有超百万常住人口&#xff0c;国内生产总值在2022年成功跨越千亿元大关。然而&#xff0c…

RocketMQ源码学习笔记:源码启动NameServer,Broker

这是本人学习的总结&#xff0c;主要学习资料如下 马士兵教育rocketMq官方文档 目录 1、Overview2、NameServer2.1、源码启动NameServer 3、Broker启动过程 1、Overview 这篇文章的源码的版本是release-4.9.8。在启动各个模块之前应该先对项目进行打包mvn install -Dmaven.te…

OS复习笔记ch9-1

单处理器调度 调度类型 主要类型 长程调度&#xff1a;决定将哪个进程放入进程池中 中程调度&#xff1a;决定将哪些进程部分或者全部放入内存中 短程调度&#xff1a;决定哪个空闲进程上处理机 I/O调度&#xff1a;决定哪个进程的I/O请求被可用的I/O设备处理 处理器调度和进…

jupyter notebook中使用不同的anaconda环境及常用conda命令

conda命令 在jupyter notebook中使用不同的anaconda环境其他常用conda命令 在jupyter notebook中使用不同的anaconda环境 创建环境 myenvname 需替换为自己的环境名称 conda create --name myenvname python3.7激活环境 conda activate myenvname 在该环境中安装Jupyter N…

springboot原理篇-springboot

springboot原理篇-springboot&#xff08;三&#xff09; 一、起步依赖 虽然我是直接学习springboot的&#xff0c;没有经历过使用spring开发&#xff0c;但是鉴于我还学习了c,对依赖这方面真的一言难尽&#xff01;springboot起步依赖解决依赖问题我实在是羡慕&#xff01; 直…