设计模式系列:简单工厂模式

news/2024/5/21 11:29:20
作者持续关注 WPS二次开发专题系列,持续为大家带来更多有价值的WPS二次开发技术细节,如果能够帮助到您,请帮忙来个一键三连,更多问题请联系我(QQ:250325397)

目录

定义

特点

使用场景

优缺点

(1) 优点

(2) 缺点

模式结构

具体实现

实际应用


定义

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

特点

在创建一个对象时不向客户暴露内部细节,并提供一个创建对象的通用接口。

使用场景

在以下情况下可以使用简单工厂模式:

工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。

客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。

举例:

一个简单的软件应用场景,一个软件系统可以提供多个外观不同的按钮(如圆形按钮、矩形按钮、椭圆按钮等), 这些按钮都源自同一个基类,不过在继承基类后不同的子类修改了部分属性从而使得它们可以呈现不同的外观,如果我们希望在使用这些按钮时,不需要知道这些具体按钮类的名字,只需要知道表示该按钮类的一个参数,并提供一个调用方便的方法,把该参数传入方法即可返回一个相应的按钮对象,此时,就可以使用简单工厂模式。

优缺点

(1) 优点
    • 通过使用工厂类,外界不再需要关心如何创造各种具体的产品,只要提供一个产品的名称作为参数传给工厂,就可以直接得到一个想要的产品对象,并且可以按照接口规范来调用产品对象的所有功能(方法)。
    • 构造容易,逻辑简单。
(2) 缺点
    • 简单工厂模式中的if else判断非常多,完全是Hard Code,如果有一个新产品要加进来,就要同时添加一个新产品类,并且必须修改工厂类,再加入一个 else if 分支才可以, 这样就违背了 “开放-关闭原则”中的对修改关闭的准则了。当系统中的具体产品类不断增多时候,就要不断的修改工厂类,对系统的维护和扩展不利。
    • 一个工厂类中集合了所有的类的实例创建逻辑,违反了高内聚的责任分配原则,将全部的创建逻辑都集中到了一个工厂类当中,所有的业务逻辑都在这个工厂类中实现。什么时候它不能工作了,整个系统都会受到影响。因此一般只在很简单的情况下应用,比如当工厂类负责创建的对象比较少时。
    • c简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

模式结构

简单工厂模式包含如下角色:

  • Factory:工厂角色

工厂角色负责实现创建所有实例的内部逻辑

  • Clickable:抽象产品角色

抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口

  • CircleButton:具体产品角色

具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。

具体实现

/*** 产品接口--抽象按钮*/
public interface Clickable {/*** 响应按钮点击*/void onClick();
}/*** 具体产品--圆形按钮*/
public class CircleButton implements Clickable {@Overridepublic void onClick() {System.out.println("button click: CircleButton...");}
}
/*** 工程模式--简单工厂*/
public class SimpleFactory {/*** 创建按钮* @param type 按钮类型,1:圆形按钮;2:椭圆形按钮;3:矩形按钮,默认:矩形按钮,可用常量或者枚举代替* @return 具体按钮*/public static Clickable createButton(int type) {Clickable button = null;switch (type) {case 1: //圆形按钮button = new CircleButton();break;case 2: //椭圆形按钮button = new OvalButton();break;case 3: //矩形按钮button = new RectangleButton();break;default:    //矩形按钮break;}return button;}
}

具体使用

public class App {public static void main(String[] args) {//1:圆形按钮Clickable circleButton = SimpleFactory.createButton(1);circleButton.onClick();//2:椭圆形按钮Clickable ovalButton = SimpleFactory.createButton(2);ovalButton.onClick();//3:矩形按钮Clickable rectangleButton = SimpleFactory.createButton(3);rectangleButton.onClick();}
}

实际应用

① JDK类库中广泛使用了简单工厂模式,如工具类java.text.DateFormat,它用于格式化一个本地日期或者时间。

public final static DateFormat getDateInstance();
public final static DateFormat getDateInstance(int style);
public final static DateFormat getDateInstance(int style,Locale locale);

②Java加密技术

获取不同加密算法的密钥生成器:

KeyGenerator keyGen=KeyGenerator.getInstance("DESede");

创建密码器:

Cipher cp=Cipher.getInstance("DESede");

http://www.mrgr.cn/p/88078558

相关文章

2.JavaScript

变量/对象 声明 var - 绑定到window,无法清理,且重复声明会污染全局(尽量不用) let - 只在 let 命令所在的代码块 {} 内有效 const - 与let类似但它是只读常量,值不可修改 参考视频 增删改查 let obj={}//创建对象 obj.a=1//新增属性a,值为1 obj[1]=1//新增属性1,值为1(…

【Jenkins】Jenkins自动化工具介绍

目录 技术背景常规的手动打包步骤 Jenkins简介起源与发展Jenkins的核心价值1.自动化1.1代码构建1.2测试自动化1.3自动部署 2.持续集成与持续部署CI/CD的概念如何减少集成问题更快速地发布软件版本 Jenkins优势Jenkins的主要竞争对手Travis CI:CircleCI:GitLab CI: Jenkins与其他…

JVM主要知识点详解

目录 1. 性能监控和调优 1.1 调优相关参数 1.2 内存泄漏排查 1.3 cpu飙⾼ 2. 内存与垃圾回收 2.1JVM的组成(面试题) 2.2 Java虚拟机栈的组成 2.3 本地方法栈 2.4 堆 2.5 方法区(抽象概念) 2.5.1 方法区和永久代以及元空…

20. 缓冲池

缓冲池介绍每次读写数据都是通过Buffer Pool;当Buffer Pool中没有用户所需要的数据时,才去硬盘中获取;通过innodb_buffer_pool_size进行设置总容量; 该值设置的越大越好; innodb_buffer_pool_instances 设置为多少个缓冲池;总容量 还是 innodb_buffer_pool_size 设置 多个…

python-常用数据结构(2)

6、某企业为职工发放奖金:如果入职超过5年,且销售业绩超过15000元的员工,奖金比例为0.2;销售业绩超过10000元的员工,奖金比例为0.15:销售业绩超过5000元的员工,奖金比例为0.1;其他奖金比例为0.05。如果是人职不超过5年,且销售业绩超过4000的员工,奖金比例为0.045;否则为0.01。输…

jenkins拉取github代码报错问题解决

问题起因: 踩坑踩坑 用jenkins拉取github项目的代码时,配置完成点击构建时,报错信息为:Couldnt find any revision to build. Verify the repository and branch configuration for this job. 解决方式: jenkins拉取git项目时,默认使用的主分支是master,gitee项目的默认…

为什么钱难赚? 因为你想的到和想不到的方向, 都有人在做了

赚钱三途:钱生钱、资源换现、劳力智力。多数人仰赖后者,却遭遇市场饱和、创新先被占位。以自媒体工具为例,“集中分发”表面蓝海实则竞争炽热,专业需求复杂,非业内者难以精准满足。虽有技术,个人开发者受限API权限、资质,难与大厂较量。赚钱的种类 大家都知道, 赚钱无非…

3dmax云渲染100怎么收费?渲染100邀请码1a12

3dmax云渲染平台有很多,它们的收费标准是什么?这次我们一起来看看吧。 以渲染100云渲染平台为例,它的价格分为以下几个档次:1、48线程 48线程是价格最低的档次,使用单台服务器渲染,价格是2.7元每小时&#…

MyBatis-08-Spring的MyBatis Interceptor

addInterceptor3个地方XML 解析的 SqlSessionFactoryBean: 生成 SqlSession 的 FactoryBean PageHelperAutoConfiguration: 分页助手的自动配置SqlSessionFactoryBean 发现现在都没有将他作为一个 FactoryBean 使用了 getObject 调用了 afterPropertiesSet 生成 SqlSessionFact…

性能测试汇总一

目录 性能测试流程​编辑性能相关概念 什么是新能测试 性能测试思维 性能测试环境要求 负载测试 压力测试 可靠性测试 稳定性测试 压力测试 容量测试 性能指标 并发用户数 响应时间 TPS 吞吐量 吞吐率 QPS 性能测试流程 测试准备 性能测试环境搭建 性能测试…

第1章:自动驾驶车辆“规划”与“控制”的通用架构

1.1 自动驾驶的分级 2014年美国汽车工程师学会 (SAE) 定义了6个无人驾驶等级,从0级(完全手动)到5级(完全自动),这些无人驾驶等级准则已经被美国交通部采纳;该标准也被称为SAE标准; …

[Java、Android面试]_18_详解Handler机制 常见handler面试题(非常重要,非常高频!!)

本人今年参加了很多面试,也有幸拿到了一些大厂的offer,整理了众多面试资料,后续还会分享众多面试资料。 整理成了面试系列,由于时间有限,每天整理一点,后续会陆续分享出来,感兴趣的朋友可关注收…

结对编程-c++四则运算

题目: 小学老师要每周给同学出300道四则运算练习题。 –这个程序有很多种实现方式: C/C++ C#/VB.net/Java Excel Unix Shell Emacs/Powershell/Vbscript Perl Python –两个运算符,100 以内的数字,不需要写答案。 –需要检查答案是否正确,并且保证答案在 0..100 之间 –尽可…

重载全局的new和delete

重载全局的new和delete ::operator new ::operator new[] -> 不可以被声明与同一个namespace之内 new会执行三个动作: -> 之前的代码提到:new本身会开辟内存空间.所以声明方法需要一个size_t size的参数inline void* operator new(size_t size) {}::operator delete ::op…

django celery 异步任务 异步存储

环境:win11、python 3.9.2、django 4.2.11、celery 4.4.7、MySQL 8.1、redis 3.0 背景:基于django框架的大量任务实现,并且需要保存数据库 时间:20240409 说明:异步爬取小说,并将其保存到数据库 1、创建…

QT 串口助手 学习制作记录

QT 串口助手qt 学习制作记录 参考教程:​​​​​​QT初体验:手把手带你写一个自己的串口助手_qt设计串口助手的流程图-CSDN博客 Qt之串口编程(添加QSerialPort模块)_如何安装 qt串口模块教程-CSDN博客 串口调试助手&#xff1…

Markdown的基本语法

Markdown的基本语法 参考来源:Markdown 教程 、手把手教会你使用Markdown 、Cmd Markdown 01、标题 1.1、# 号使用 使用 # 号可以表示 1-6 级标题,一级标题对应一个 # 号,随着 # 的个数递增,一级标题字号最大,六级标题字号最小。 代码如下: # 一级标题 ## 二级标题 ### 三…

Swoole 实践篇之结合 WebRTC 实现音视频实时通信方案

原文首发链接:Swoole 实践篇之结合 WebRTC 实现音视频实时通信方案 大家好,我是码农先森。 引言 这次实现音视频实时通信的方案是基于 WebRTC 技术的,它是一种点对点的通信技术,通过浏览器之间建立对等连接,实现音频和视频流数据的传输。 在 WebRTC 技术中通常使用 WebSoc…

【数据结构与算法】:10道链表经典OJ

目录 1. 移除链表元素2. 反转链表2.1反转指针法2.2 头插法 3. 合并两个有序链表4. 分隔链表5. 环形链表6. 链表的中间节点7. 链表中倒数第K个节点8. 相交链表9. 环形链表的约瑟夫问题10. 链表的回文结构 1. 移除链表元素 思路1:遍历原链表,将 val 所在的…

JS:locaton.href=易错点

这个地方我错了两次了,每次还让人找得焦头烂额,或许记下来能让我长点记性 易错写法: 正确写法: 不知道为什么我每次都写成location.href("#"),明明应该是location.href="#",而且因为它并不报错,我这笨脑瓜差错真的很心累