简单工厂模式详解

news/2024/4/28 20:08:25/文章来源:https://blog.csdn.net/qq_40187702/article/details/131735715

文章目录

  • 前言
  • 一、简单工厂模式定义
  • 二、举个例子
  • 三、简单工厂模式的缺点
  • 总结


前言

本篇我们了解一下简单工厂模式,它是设计模式的雏形,是学习设计模式的开端,我会结合案例说明它的设计思路。


一、简单工厂模式定义

简单工厂模式并不是GoF23个设计模式中的一员,但是一般将它作为学习设计模式的起点。简单工厂模式又称为静态方法模式(Static Factory Method Pattern),属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同的类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,这个类称为工厂类,被创建的实例通常都具有共同的父类。简单工厂模式的结构如下图:
在这里插入图片描述
在模式结构图中,Factory表示工厂类,它是整个模式的核心,负责实现创建所有实例的内部逻辑。工厂类可以被外部直接调用,创建所需的产品对象。工厂类中有一个负责生产对象的静态工厂方法,系统可以根据工厂方法所传入的参数,动态决定应该创建出哪一个产品类的实例。工厂方法是静态的,而且必须有返回类型,其返回类型为抽象产品类型,即Product类型;Product表示抽象产品角色,它是简单工厂模式所创建的所有对象的父类,负责定义所有实例所共有的公共接口;ConcreteProduct表示具体产品角色,它是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。一个系统中一般存在多个ConcreteProduct类,每种具体产品对应一个Concrete类。

二、举个例子

我们设计一个Coffee(咖啡类),它是一个抽象类,比如现在有两种具体咖啡,分别是AmericanCoffee(美式咖啡)和LatteeCoffee(拿铁咖啡),因此我们需要一个具体工厂去创建具体咖啡产品,我们再定义一个生产咖啡的工厂SimpleCoffeeFactory,它们的模式结构图如下:
在这里插入图片描述
AmericanCoffee和LatteeCoffee需要继承Coffee这个抽象产品,同时都要实现Coffee中的抽象方法,比如获取咖啡名称,添加牛奶,加糖等方法,而SimpleCoffeeFactory是生产咖啡的工厂,需要提供一个静态的创建咖啡的方法,同时这个方法的返回值类型必须是Coffee抽象类,这就体现了多态的特性,即父类引用可以指向子类对象。
相关代码如下:
抽象咖啡类,其实也可以是接口,我定义的是抽象类:

abstract public class Coffee {abstract protected void getName();abstract protected void addMilk();abstract protected void addSugar();
}

美式咖啡(具体产品):

public class AmericanCoffee extends Coffee{@Overrideprotected void getName() {System.out.println("American Coffee...");}@Overrideprotected void addMilk() {System.out.println("add American coffee milk...");}@Overrideprotected void addSugar() {System.out.println("add American coffee sugar...");}
}

拿铁咖啡(具体产品):

public class LatteCoffee extends Coffee{@Overrideprotected void getName() {System.out.println("Latte Coffee...");}@Overrideprotected void addMilk() {System.out.println("add Latte Coffee milk...");}@Overrideprotected void addSugar() {System.out.println("add Latte Coffee sugar...");}
}

咖啡工厂类:

public class SimpleCoffeeFactory {public static Coffee createFactory(String type){Coffee coffee = null;if ("AmericanCoffee".equals(type)){coffee = new AmericanCoffee();} else if ("LatteeCoffee".equals(type)) {coffee = new LatteCoffee();}return coffee;}
}

在咖啡工厂类中定义了一个创建咖啡的静态方法,入参是咖啡的类型,根据类型判断返回具体咖啡对象。
在外部可以创建一个咖啡店类,调用工厂提供的静态方法去创建具体的咖啡:

public class CoffeeStory {public static void main(String[] args) {orderCoffee("AmericanCoffee");}public static Coffee orderCoffee(String name){SimpleCoffeeFactory simpleCoffeeFactory = new SimpleCoffeeFactory();Coffee coffee = simpleCoffeeFactory.createFactory(name);coffee.getName();coffee.addMilk();coffee.addSugar();return coffee;}
}

三、简单工厂模式的缺点

在简单工厂模式中,工厂类包含必要的判断逻辑,决定在什么时候创建哪一个产品类的实例,客户端可以直接免除直接创建产品对象的责任,而仅仅“消费”产品,简单工厂模式通过这种方式实现了对责任的划分。但是由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响;同时系统扩展较为困难,一旦添加新产品就不得不修改工厂逻辑,违反了开闭原则。比如上面的案例,如果我们再增加一种意大利咖啡,那么在创建具体产品类的同时,静态工厂方法的代码逻辑需要改动。因此,简单工厂模式是存在很多问题的,通常并不用于实际开发中。


总结

本篇我们结合实际案例说明了简单工厂模式的设计原理,和它包含的角色,下面我们继续看另一种设计更合理的工厂方法模式。

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

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

相关文章

【运维工程师学习五】数据库之MariaDB

【运维工程师学习五】数据库 1、常用的关系型数据库2、C/S结构3、MariaDB图形客户端4、安装MariaDB5、启动MariaDB及验证启动是否成功6、验证启动——端口7、验证启动——进程8、MariaDB配置文件路径主配置文件解读: 9、MariaDB的配置选项10、MariaDB客户端连接1、在…

华为云子网路由表作用及价值

子网路由表 子网路由表作用云专线、VPN的配置与子网路由表强关联,本质是在相应的子网路由表中添加了一条路由Nat路由表问题地址变更问题snat和dnat 子网路由表作用 子网内部作为一个二层网络,通过mac地址互通,不通过路由互通。跨子网&#x…

微信小程序安装和使用 Vant Weapp 组件库

微信小程序安装和使用 Vant Weapp 组件库 1. Vant Weapp 介绍2. Vant Weapp 的 安装2.1. 通过npm安装2.2. 构建npm2.3. 修改 app.json2.4. 修改 project.congfig.json2.5. 测试一下,使用Vant Weapp提供的组件 1. Vant Weapp 介绍 Vant 是一个轻量、可靠的移动端组件…

Three.js环境光,平行光,点光源,聚光灯的创建和灯光辅助线的使用

Three.js中的灯光API使用 1.环境光(AmbientLight)2.平行光(directionalLight)3.PointLight(点光源) 4.聚光灯(SpotLight)5.材质平面(PlaneGeometry)用于接收(平行光和聚…

JavaWeb项目【SpringBoot】——图书项目4.0【源码】:SpringBoot版本 springboot相关技术 项目应用

目录 项目简介思考 & 改进1.Jsp都是同步请求---->改成异步Ajax【完成】2.前端用Jsp技术落后----->用Vue框架【完成】3.架构问题:配置数据和Java代码耦合【完成】3.SQL语句和Java代码耦合【完成】4.架构问题:servlet只能处理一个请求5.响应方式…

[论文分享]MR-MAE:重构前的模拟:用特征模拟增强屏蔽自动编码器

论文题目:Mimic before Reconstruct: Enhancing Masked Autoencoders with Feature Mimicking 论文地址:https://arxiv.org/abs/2303.05475 代码地址:https://github.com/Alpha-VL/ConvMAE(好像并未更新为MR-MAE模型) …

从Vue2到Vue3【零】——Vue3简介及创建

系列文章目录 内容链接从Vue2到Vue3【零】Vue3简介及创建 文章目录 系列文章目录前言一、Vue3的发布带来了什么1.1 性能提升1.2 源码升级1.3 支持TypeScript1.4 新特性 二、创建Vue3.0工程2.1 什么是Vite2.2 利用Vite创建Vue3.0工程2.3 利用vue-cli脚手架创建Vue3.0工程 三、 …

美团JVM面试题

1. 请解释一下对象创建的过程? Java对象创建的过程主要分为以下五个步骤: 类加载检查 Java虚拟机在读取一条new指令时候,首先检查能否在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化。如果没有&a…

C#开发的OpenRA游戏之维修按钮

C#开发的OpenRA游戏之维修按钮 前面分析物品的变卖按钮,如果理解这个流程,再看其它按钮的流程,其实是一样的,所以前面的文章是关键,只有理解通透的基础之上,才能继续往下。 维修按钮的存在价值,就是当建筑物受到敌方破坏,还没有完全倒掉之前,可以使用金币来进行修理。…

快速排序的非递归实现、归并排序的递归和非递归实现、基数排序、排序算法的时间复杂度

文章目录 快速排序的非递归三数取中法选取key快速排序三路划分 归并排序的递归归并排序的非递归计数排序稳定性排序算法的时间复杂度 快速排序的非递归 我们使用一个栈来模拟函数的递归过程,这里就是在利用栈分区间。把一个区间分为 [left,keyi-1][key][keyi1,right…

Android 进程与进程之间的通信--AIDL详细教程,以传递对象为例,两个app实现

我这里案例是 通过 IPC 传递对象 (以DemoBean类为例) 如下: AIDL 使用一种简单语法,允许您通过一个或多个方法(可接收参数和返回值)来声明接口。参数和返回值可为任意类型,甚至是 AIDL 生成的其…

如何将jar 包下载到自定义maven仓库

下载命令 mvn install:install-file -Dfileartifactid-version.jar -DgroupIdgroupid -DartifactIdartifactid -Dversionversion -Dpackagingjar -DlocalRepositoryPath. -DcreateChecksumtrue参数解释 在上述命令中,需要替换以下参数: artifactid-vers…

计算机组成原理课程设计 报告

在我的博客查看:https://chenhaotian.top/study/computer-composition-principles-course-design/ 计算机组成原理课程设计 报告 一、目的和要求 深入了解计算机各种指令的执行过程,以及控制器的组成,指令系统微程序设计的具体知识&#xf…

【前端知识】React 基础巩固(二十六)——Portals 的使用

React 基础巩固(二十六)——Portals 的使用 Portals 通常&#xff0c;组件会渲染到 root 节点下。可使用 Portals 将组件渲染至其他节点。 添加 id 为 more、modal 的 div 元素 <div id"root"></div> <div id"more"></div> &l…

工作:三菱PLC之CC-Link IE Field Network通讯知识及应用

工作&#xff1a;三菱PLC之CC-Link IE Field Network通讯知识及应用 一、理论 1. 简介连接 CC-LINK-IE通讯分别有 CC-Link IE TSN&#xff0c;CC-Link IE Control Network&#xff0c;CC-Link IE Field Network&#xff0c;CC-Link IE Field Network Basic几种形式&#xff…

成功解决wget下载报错 : wget HTTP request sent, awaiting response... 403 Forbidden

成功解决wget下载报错 : wget HTTP request sent, awaiting response... 403 Forbidden 问题描述解决方案原理什么是User Agent解决 问题描述 –2023-07-15 02:32:57-- https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2023.03-Linux-x86_64.sh Resolving mi…

PyTorch: 池化-线性-激活函数层

文章和代码已经归档至【Github仓库&#xff1a;https://github.com/timerring/dive-into-AI 】或者公众号【AIShareLab】回复 pytorch教程 也可获取。 文章目录 nn网络层-池化-线性-激活函数层池化层最大池化&#xff1a;nn.MaxPool2d()nn.AvgPool2d()nn.MaxUnpool2d()线性层激…

linux 下如何安装 tar.gz包

linux 下如何安装 tar.gz包 解压缩进入解压后的文件目录下 解压缩 tar -zxvf pycharm-community-2023.1.3.tar.gz进入解压后的文件目录下 ./pycharm.sh可执行Pycharm 建议将目录转移到其他位置 我习惯使用2020版本的 下载地址

源码阅读: echo 回显程序

文章目录 1. 目的2. 原始代码3. 化简和跨平台支持4. 修改后代码的代码分析5. References 1. 目的 阅读 netbsd 9.3 的 echo.c, 练习 C 语言源码阅读的技能。 2. 原始代码 https://github.com/NetBSD/src/blob/trunk/bin/echo/echo.c /* $NetBSD: echo.c,v 1.23 2021/11/16 …

2023年Java最新面试题

由【后端面试题宝典】提供 和 equals 的区别是什么&#xff1f; 对于基本类型&#xff0c;比较的是值&#xff1b;对于引用类型&#xff0c;比较的是地址&#xff1b;equals不能用于基本类型的比较&#xff1b;如果没有重写equals&#xff0c;equals就相当于&#xff1b;如果重…