设计模式——简单工厂模式

设计模式——简单工厂模式

  • 什么是简单工厂模式
  • 简单工厂模式的优点

我们今天接着来看设计模式的简单工厂模式,如果还没看过上一篇的单列模式的小伙伴可以点击这里:

https://blog.csdn.net/qq_67693066/article/details/136603292

什么是简单工厂模式

简单工厂模式(Simple Factory Pattern)是一种编程设计模式,属于创建型设计模式的范畴,它提供了一种集中管理和控制对象创建的方式,让客户端不必了解具体的创建逻辑。简单工厂模式的核心概念是一个“工厂类”,该类负责创建一系列相关或相互依赖的对象,而不是让客户端直接去new具体的对象。

在简单工厂模式中,客户端请求工厂对象来创建一个产品对象,而客户端并不关心具体产品的创建细节。例如,工厂可以根据传入的不同参数创建不同类型的对象,这些对象通常是具有共同接口或基类的一系列具体产品。

简单工厂模式的结构主要包括以下几个部分:

  1. 抽象产品(Abstract Product):定义了产品的接口或抽象类,它是所有具体产品类的公共父类或接口。
  2. 具体产品(Concrete Product):实现了抽象产品接口的具体产品类,每个具体产品对应工厂可能创建的一种产品对象。
  3. 工厂(Factory):负责创建具体产品的类,根据传入的参数来决定创建哪种具体产品对象。

简单工厂模式的一个主要优点是可以将对象的创建过程封装起来,简化客户端代码,隐藏实现细节;缺点是当需要添加新产品时,需要修改工厂类的代码,违反了开闭原则(Open/Closed Principle)。在实际应用中,当产品种类有限且扩展性需求不高时,简单工厂模式是一个实用的选择。

比如我们利用制作咖啡的例子来说明一下:

//pragma once 用于防止头文件被重复包含,确保头文件内容仅被编译一次
#pragma once// 引入必要的标准库头文件
#include<iostream> // 用于输出和输入操作
#include<cstring> // 提供字符串处理函数,此处可能并未直接使用,可以考虑是否真的需要
#include<memory> // 提供智能指针等内存管理工具,此处用于std::unique_ptr// 抽象产品类(咖啡接口)
class Coffee
{
public:// 声明纯虚函数,表示Coffee为抽象类,任何尝试实例化Coffee对象的行为都是非法的virtual std::string get_coffee_name() const = 0; // 获取咖啡名称的纯虚函数virtual double get_coffee_price() const = 0; // 获取咖啡价格的纯虚函数// 提供默认的析构函数,由于Coffee是抽象类,一般不需要提供特殊实现virtual ~Coffee() {} // 默认析构函数
};// 具体的产品(美国咖啡)
class AermicanCoffe : public Coffee
{
public:// 重写抽象基类Coffee的纯虚函数std::string get_coffee_name() const override{return "AermicanCoffe";}double get_coffee_price() const override{return 3.78;}
};// 具体的产品(中国咖啡)
class ChinaCoffe : public Coffee
{
public:// 重写抽象基类Coffee的纯虚函数std::string get_coffee_name() const override{return "ChinaCoffe";}double get_coffee_price() const override{return 3.98;}
};// 工厂类,用于根据传入的类型创建相应咖啡对象的智能指针
class CoffeeFactory
{
public:// 静态成员函数,创建并返回指向具体咖啡类型的唯一智能指针static std::unique_ptr<Coffee> createCoffee(const std::string& type){if(type == "AermicanCoffe"){// 创建并返回指向AermicanCoffe类型的智能指针return std::make_unique<AermicanCoffe>();}else if(type == "ChinaCoffe"){// 创建并返回指向ChinaCoffe类型的智能指针return std::make_unique<ChinaCoffe>();}else{// 输入的类型无效,输出错误信息,并返回空智能指针std::cout<<"Error type"<<std::endl;return nullptr;}}
};

在main函数中写到:

#include"Coffee.h"int main()
{auto coffee1 = CoffeeFactory::createCoffee("AermicanCoffe");std::cout << "Ordered coffee: " << coffee1->get_coffee_name()<< std::endl;std::cout << "Price: " << coffee1->get_coffee_price()<< std::endl;auto coffee2 = CoffeeFactory::createCoffee("ChinaCoffe");std::cout << "Ordered coffee: " << coffee2->get_coffee_name()<< std::endl;std::cout << "Price: " << coffee2->get_coffee_price()<< std::endl;return 0;
}

在这里插入图片描述

简单工厂模式的优点

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它在软件设计中具有以下优点:

  1. 封装创建逻辑:简单工厂模式将对象的创建过程封装在一个工厂类中,客户端不需要知道具体的创建步骤和逻辑,只需传递必要的参数,就能得到想要的产品对象,降低了客户端与具体产品类的耦合度。
  2. 简化客户端代码:客户端只需调用工厂类的方法,不用关心创建对象的具体细节,简化了客户端代码,提高了代码的可读性和可维护性。
  3. 新增产品方便:如果要新增一种产品,只需新增一个产品类,并在工厂类中添加相应的创建逻辑,客户端代码基本无需修改,增强了系统的扩展性。
  4. 统一入口点:通过工厂类,可以控制哪些类可以被实例化,从而更容易控制全局的对象创建规则,例如实现单例模式或者限制特定环境下只能创建某种类型的产品。
  5. 便于切换实现:通过修改工厂类的内部逻辑,可以在不改变客户端代码的情况下切换产品的具体实现,提高了系统的灵活性。

比如我现在想增加一个泰国咖啡,我只需要在后面加就可以了:
在这里插入图片描述修改一下工厂类:

在这里插入图片描述在这里插入图片描述

然而,简单工厂模式也有一些局限性,例如它违反了开闭原则(Open/Closed Principle),每增加一个新的具体产品,就需要修改工厂类的代码,而且随着产品种类的增多,工厂类可能会变得庞大而难以维护。在大规模的系统设计中,可能需要考虑工厂方法模式或抽象工厂模式等更为灵活的设计方案。

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

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

相关文章

【c语言】结构体的访问

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…

宏景eHR customreport/tree SQL注入漏洞复现

0x01 产品简介 宏景eHR人力资源管理软件是一款人力资源管理与数字化应用相融合,满足动态化、协同化、流程化、战略化需求的软件。 0x02 漏洞概述 宏景eHR customreport/tree 接口处存在SQL注入漏洞,未经过身份认证的远程攻击者可利用此漏洞执行任意SQL指令,从而窃取数据库…

【cocos creator】【TS】贝塞尔曲线,地图之间显示曲线,顺着曲线移动

参考&#xff1a; https://blog.csdn.net/Ctrls_/article/details/108731313 https://blog.csdn.net/qq_28299311/article/details/104009804 const { ccclass, property } cc._decorator;ccclass export default class mapPanel extends cc.Component {property(cc.Node)pla…

力扣HOT100 - 41. 缺失的第一个正数

解题思路&#xff1a; 原地哈希 就相当于&#xff0c;让每个数字n都回到下标为n-1的家里。 而那些没有回到家里的就成了孤魂野鬼流浪在外&#xff0c;他们要么是根本就没有自己的家&#xff08;数字小于等于0或者大于nums.size()&#xff09;&#xff0c;要么是自己的家被别…

试题 C: 质因数个数

萎了&#xff0c;整个人都萎了 快三天都没刷题了&#xff0c;想着明天就蓝桥杯了&#xff0c;就找了个真题做了下 可以看得出来这题很简单 但是没有测试点给我用&#xff0c;所以我的代码不保证正确性 代码如下&#xff1a; #include<cstdio> #include<cmath> …

014:vue3 van-list van-pull-refresh实现上拉加载,下拉刷新

文章目录 1. 实现上拉加载&#xff0c;下拉刷新效果2. van-list&#xff0c;van-pull-refresh组件详解2.1 van-list组件2.2 van-pull-refresh组件 3. 完整案例4. 坑点&#xff1a;加载页面会一直调用加载接口 1. 实现上拉加载&#xff0c;下拉刷新效果 通过下拉刷新加载下一页…

20240405,数据类型,运算符,程序流程结构

是我深夜爆炸&#xff0c;不能再去补救C了&#xff0c;真的来不及了&#xff0c;不能再三天打鱼两天晒网了&#xff0c;真的来不及了呜呜呜呜 我实在是不知道看什么课&#xff0c;那黑马吧……MOOC的北邮的C正在进行呜呜 #include <iostream> using namespace std; int…

力扣 | 54. 螺旋矩阵

注意按照顺时针方向进行访问元素&#xff0c;以及每次触发的条件只会满足一个&#xff01; public List<Integer> spiralOrder(int [][] matrix){List<Integer> result new ArrayList<>();int m matrix.length;int n matrix[0].length;int row0,col 0;//…

【汇编】计算机系统构成

计算机系统构成 计算机系统包括硬件和软件两部分 硬件 典型的计算机结构包括 中央处理器(CPU)、存储器和输入输出(I/O)子系统 三个主要组成部分&#xff0c;用系统总线把它们连接在一起 计算机硬件组成与各部分之间的联系 软件 计算机软件可以分为系统软件和用户软件两大类 …

react17中配置webpack:使用@代表src目录

在vue的项目中可以使用表示src目录&#xff0c;使用该符号表示绝对路径&#xff0c;那么在react中想要使用怎么办呢&#xff1f; 在react中使用表示src目录是需要在webpack中配置的&#xff0c;在核心模块node_modules-》react-scripts-》config-》webpack.config.js中搜索找到…

必应bing搜索广告推广国内能开户吗?

随着互联网广告市场的不断进化和细分化&#xff0c;必应Bing搜索广告已逐渐成为中国企业拓展国内市场、精准触达目标客户的重要渠道之一。2024年&#xff0c;必应Bing在国内市场的进一步布局&#xff0c;不仅彰显了其对本土企业的强大吸引力&#xff0c;更带来了全新的开户政策…

Java基础入门--第十一章--JDBC(Java Database Connection)Java数据库连接

JDBC 11.1 什么是JDBC11.1.1 JDBC概述11.1.2 JDBC驱动程序 11.2 JDBC的常用API11.3 JDBC编程11.3.1 JDBC 编程步骤11.3.2 实现第一个JDBC程序 我的MySQL的root密码: root 11.1 什么是JDBC 11.1.1 JDBC概述 JDBC的全称是Java数据库连接&#xff08;Java Database Connectivit…

React - 你知道props和state之间深层次的区别吗

难度级别:初级及以上 提问概率:60% 如果把React组件看做一个函数的话,props更像是外部传入的参数,而state更像是函数内部定义的变量。那么他们还有哪些更深层次的区别呢,我们来看一下。 首先说props,他是组件外部传入的参数,我们知道…

【React】React18+Typescript+craco配置最小化批量引入Svg并应用的组件

React18Typescriptcraco配置最小化批量引入Svg并应用的组件 前言创建React Typescript项目通过require.context实现批量引入Svg安装[types/webpack-env](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.zh-Hans.md)解决类型报错安装[craco](https://…

数据中心的网络架构设计,打造高效、安全的数字底座

数据中心的网络架构设计 一、数据中心网络架构设计原则 网络,作为数据中心的核心支柱,其结构精妙,由众多二层接入设备与少量三层设备共同编织而成。过去,数据中心网络规模有限,仅凭数十台设备的简单互连便能实现信息的畅通无阻。然而,随着技术与应用需求的飞速增长,数据…

16. 网络编程(1)

Hi,大家好!从本节开始我们学习网络编程相关的知识。基于TCP服务器和客户端实现流程框架。 本节目录: 网络编程在软件开发中具有相当重要的作用,涉及到各方各面: 网络通信: Linux系统作为一个多用户、多任务的操作系统,网络通信是其重要的功能之一。通过网络编程,可以实现…

Rust面试宝典第2题:逆序输出整数

题目 写一个方法&#xff0c;将一个整数逆序打印输出到控制台。注意&#xff1a;当输入的数字含有结尾的0时&#xff0c;输出不应带有前导的0。比如&#xff1a;123的逆序输出为321&#xff0c;8600的逆序输出为68&#xff0c;-609的逆序输出为-906。 解析 这道题本身并没有什么…

域控软件安全隔离关键技术剖析:MCU域 VS SOC域

安全隔离的需求 功能安全开发中&#xff0c;软件阶段由软件V模型左边的软件安全需求SSR开始。SSR是从技术安全需求TSR中提取出软件的功能安全需求&#xff0c;大多数情况下具有不同的ASIL等级。 图1 功能安全软件开发V模型 随后&#xff0c;软件安全需求会被分配到软件架构中的…

LeetCode110:平衡二叉树

题目描述 给定一个二叉树&#xff0c;判断它是否是 平衡二叉树 解题思想 使用递归依次计算左子树的高度和右子树的高度 代码 class Solution { public:int height(TreeNode* node) {if (node nullptr) return 0;int leftT height(node->left);if (leftT -1) return -1;…

Kivy 学习2

from kivy.app import App from kivy.uix.button import Button from kivy.uix.floatlayout import FloatLayout from kivy.graphics import Rectangle, Colorclass FloatLayoutApp(App):def build(self):def update_rect(layout, *args):设置背景尺寸&#xff0c;可忽略layout…