软件设计之工厂方法模式
工厂方法模式指定义一个创建对象的接口,让子类决定实例化哪一个类。
结构关系如下:
可以看到,客户端创建了两个接口,一个AbstractFactory,负责创建产品,一个Product,负责产品的实现。ConcreteFactory1与ConcreteFactory2实现了AbstractFactory的功能,可以分别创建ConcreteProduct1和ConcreteProduct2产品对象,两种产品对象实现了Product。
下面通过具体的案例说明工厂方法模式。
上述情景在实际开发中很常见:通过在选择框中选择相应的选项,系统会做出不同的响应。
从用户层面来说,文本域可以作为我们需要的产品,选择框可以作为工厂。
下面是具体的实现关系图。
我们先看一下工厂接口。
public interface PolicyProducer
{public AutoInsurance getInsurObj();
}
可以看到,AutoInsurance的实现类中可以通过getInsurObjla拿到产品对象。
再看一下产品接口。
public interface AutoInsurance {abstract String getInfo();
}
接口当中可以通过getInfo拿到产品的信息。
下面我们看一个产品。
public class BodyInjur implements AutoInsurance {private String description;public String getInfo() {description = " Body Injur Liability: \n\nBodily injury coverage pays for medical bills" +" lost wages, rehabilitation, treatment and/or" +" funeral costs for anyone injured or killed " +" by your car. Such coverage will also pay for" +" pain and suffering damages when a third " +" party successfully sues. ";return description;}
}
这个类实现了产品的接口,把界面文本域中的信息存储在description中,当工厂创建了这个对象,界面系统就可以通过getInfo拿到文本域中的信息。
下面看一看生产这个产品的工厂。
public class BodyPolicy implements PolicyProducer {public AutoInsurance getInsurObj() {return new BodyInjur();}
}
当需要创建一个产品的时候需要创建它的工厂,在这个工厂当中,通过getInsurObj获取对应的产品对象。
如果现在需要创建一个产品,即在本案例中需要新增一种模式,该怎么做呢?
按照工厂方法模式,需要新增两个类,一个是工厂,一个是产品。
LuxeryCarlnsurance.java
public class LuxeryCarlnsurance implements AutoInsurance{private String description;public String getInfo() {description = " Body Injur Luxery: \n\nBodily injury coverage pays for medical bills" +" lost wages, rehabilitation, treatment and/or" +" funeral costs for anyone injured or killed " +" by your car. Such coverage will also pay for" +" pain and suffering damages when a third " +" party successfully sues. ";return description;}
}
LuxeryCarPolicy.java
public class LuxeryCarPolicy implements PolicyProducer{public AutoInsurance getInsurObj() {return new LuxeryCarlnsurance();}
}
当需要这种模式的时候,你会打开选择框选择这种模式。
现在选择框里是没有这种模式的,我们就需要向选择框里添加这种模式。
public static final String LUXERY = "Luxery";
这是定义模式的描述信息,也就是我们在选择框里见到的。
对于java的swing编程,只需要在组件中加入文本信息即可,即:
cmbInsuranceType = new JComboBox();cmbInsuranceType.addItem(BODYINJURE);cmbInsuranceType.addItem(COLLISION);cmbInsuranceType.addItem(PERSONINJURE);cmbInsuranceType.addItem(PROPERTY);cmbInsuranceType.addItem(COMPREHENSIVE);cmbInsuranceType.addItem(LUXERY);
现在虽然可以显示了,但目前为止只是更新了GUI界面。
下面直接创建模式对象即可。
if (type.equals(LUXERY)) {pp = new LuxeryCarPolicy();
}
由此,我们思考一个问题,这种模式与直接创建有什么区别?
如果我直接创建对象而不创建工厂需要怎么做?
那是不是需要每次创建对象后都需要执行一定的操作。
if (type.equals(BODYINJURE)) {pp=new BodyPolicy();/** * */}else if (type.equals(COLLISION)) {pp=new CollPolicy(); /** * */}else if (type.equals(PERSONINJURE)) {pp= new PersonPolicy(); /** * */}else if (type.equals(PROPERTY)) {pp = new PropPolicy(); /** * */ } else if (type.equals(COMPREHENSIVE)) {pp= new ComPolicy(); /** * */}else if (type.equals(LUXERY)) {pp = new LuxeryCarPolicy(); /** * */}
而工厂模式下统一进行了操作。
AutoInsurance ai = pp.getInsurObj();
String desc = ai.getInfo();
txtForInfo.setText(desc);
换句话说把对象的操作抽象成抽象类的方法。
即产品接口:
下面给出工厂模式的优缺点。
主要优点:
- 用户只需要知道具体工厂的名称就可得到想要的产品,无须知道产品的具体创建过程。
- 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
- 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。
主要缺点:
- 类的个数容易过多,增加复杂度
- 增加了系统的抽象性和理解难度
- 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。
百度网盘
链接:https://pan.baidu.com/s/1qTt3UV1BN16QFdtcIt_0fA?pwd=3kgh
提取码:3kgh
相关文章:

软件设计之工厂方法模式
工厂方法模式指定义一个创建对象的接口,让子类决定实例化哪一个类。 结构关系如下: 可以看到,客户端创建了两个接口,一个AbstractFactory,负责创建产品,一个Product,负责产品的实现。ConcreteF…...

【Linux】shell运行原理及权限
主页点击直达:个人主页 我的小仓库:代码仓库 C语言偷着笑:C语言专栏 数据结构挨打小记:初阶数据结构专栏 Linux被操作记:Linux专栏 LeetCode刷题掉发记:LeetCode刷题 算法:算法专栏 C头疼…...

OA系统和ERP系统有什么区别?
在当今的企业管理领域,协同办公管理系统和ERP系统是两个非常重要的工具。它们在企业的日常运营中扮演着不同的角色,有着各自独特的功能和优势。那么,OA系统和ERP系统到底有什么区别呢?协同办公管理系统又是如何在这两者之间发挥协…...
c语言之strcat函数使用和实现
文章目录 前言一、strcat函数使用二、实现方法 前言 c语言之strcat 函数使用和实现 一、strcat函数使用 原型: char *strcat ( char * destination, const char * source );strcat追加拷贝,追加到目标空间后面,目标空间必须足够大,能容纳下…...

Halo-Theme-Hao文档:如何设置导航栏?
本篇文章会教你如何配置导航栏,最终效果参考如下。 感谢 Lanbin、小孙同学 等同学的贡献(语雀参与编辑)。 1标题 进入站点后台 点击左侧面板中的 主题 点击上方的 导航 修改 标题字段即可 2主菜单 主菜单即网站导航栏中间部分的菜单 进入站点…...

【Java学习之道】Java网络编程API介绍
引言 在Java中,进行网络编程的主要方式是通过Java网络编程API。这些API提供了一组类和接口,用于创建网络应用,如TCP和UDP通信、URL访问等。在这一节中,我们将带你领略Java网络编程API的魅力。 一、InetAddress InetAddress类是表…...

[论文笔记]SimCSE
引言 今天带来一篇当时引起轰动的论文SimCSE笔记,论文题目是 语句嵌入的简单对比学习。 SimCSE是一个简单的对比学习框架,它可以通过无监督和有监督的方式来训练。 对于无监督方式,输入一个句子然后在一个对比目标中预测它自己,仅需要标准的Dropout作为噪声。这种简单的…...
设置按键中断,按键1按下,LED亮,再按一次,灭按键2按下,蜂鸣器响。再按一次,不响按键3按下,风扇转,再按一次,风扇停
src/key_it.c #include"key_it.h" //GPIO初始化 void all_led_init() {//RCC使能RCC->MP_AHB4ENSETR | (0X1<<4);//设置PE10 PF10 PE8为输出GPIOE->MODER & (~(0X3<<20));GPIOE->MODER | (0X1<<20);//设置推挽输出GPIOE->OTYPER…...
深拷贝和浅拷贝的主要区别
在JavaScript中,深拷贝和浅拷贝的主要区别在于它们处理对象属性的方式。 浅拷贝(Shallow Copy)只复制对象的引用,而不是实际的对象。因此,如果你修改了复制的对象,原始对象也会受到影响。 深拷贝…...

Git Cherry Pick的使用
cherry-pick命令的基本用法 cherry-pick命令的基本语法如下: git cherry-pick <commit>其中,<commit>是要应用的提交的哈希值或分支名。该命令会将指定的提交应用到当前分支上,并创建一个新的提交。 使用场景 cherry-pick命令…...

vue3后台管理框架之基础配置
配置vite.config.js import { defineConfig } from viteimport vue from vitejs/plugin-vueexport default defineConfig(({ command, mode }) > {//const env loadEnv(mode, process.cwd(), ) //获取环境变量return {// 打包devbase: ./,// 开发环境server: {port: 5002,…...

Easysearch压缩模式深度比较:ZSTD+source_reuse的优势分析
引言 在使用 Easysearch 时,如何在存储和查询性能之间找到平衡是一个常见的挑战。Easysearch 具备多种压缩模式,各有千秋。本文将重点探讨一种特别的压缩模式:zstd source_reuse,我们最近重新优化了 source_reuse,使得它在吞吐量…...

扩散模型的系统性学习(一):DDPM的学习
文章目录 一、学习的资料1.1 对于扩散模型的发展过程的综述1.2对论文中涉及的公式以及公式对应的代码的解读1.3github中对于各模型实现的代码1.4相关基础知识的学习 二、DDPM的学习2.1 DDPM总体知识的梳理2.2相关代码的解读2.2.1unet 代码块2.2.2高斯扩散代码块2.2.3 实验流程代…...

注意力屏蔽(Attention Masking)在Transformer中的作用 【gpt学习记录】
填充遮挡(Padding Masking): 未来遮挡(Future Masking):...

MyBatisPlus详解
前言: 📕作者简介:热爱编程的小七,致力于C、Java、Python等多编程语言,热爱编程和长板的运动少年! 📘相关专栏Java基础语法,JavaEE初阶,数据库,数据结构和算法系列等,大家有兴趣的可以看一看。 😇😇😇有兴趣的话关注博主一起学习,一起进步吧! 一、MyBatis…...
组合数的计算
C: 即从a个元素中选取b个元素的组合数。 LL C(int a, int b) {LL res 1;for (int i a, j 1; j < b; i --, j )res res * i / j;return res; } A: 表示从a个元素中选取b个元素进行排列的情况数。 LL P(int a, int b) {LL res 1;for (int i a; i > a - b; i--){res…...
linux之shell记录
shell属于一种很容易学习的程序设计语言,依赖于功能强大的命令可以编写提高开发效率的脚本。这里记录一下常用的shell相关的知识点。 持续更新中。。。 1、在linux或mac中查看使用的shell echo $SHELL /bin/bashshell是一种脚本语言,就会有解释器来执行…...

外卖大数据案例
一、环境要求 HadoopHiveSparkHBase 开发环境。 二、数据描述 meituan_waimai_meishi.csv 是某外卖平台的部分外卖 SPU(Standard Product Unit , 标准产品单元)数据,包含了外卖平台某地区一时间的外卖信息。具体字段说明如下&am…...

到底什么是5G-R?
近日,工信部向中国国家铁路集团有限公司(以下简称“国铁集团”)批复5G-R试验频率的消息,引起了行业内的广泛关注。 究竟什么是5G-R?为什么工信部会在此时批复5G-R的试验频率? 今天,小枣君就通过…...

uniapp 使用和引入 thorui
1. npm install thorui-uni 2. "easycom": { "autoscan": true, "custom": { "tui-(.*)": "thorui-uni/lib/thorui/tui-$1/tui-$1.vue" } }, 3....

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...

jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...