系列文章目录

文章目录

  • 系列文章目录
    • 需要了解工厂制造细节吗?
    • 简单工厂模式实现
    • 工厂方法模式的实现
    • 简单方法? 工厂方法?
  • 总结


需要了解工厂制造细节吗?

我们在前面的文章中为大家介绍了简单工厂模式,我们知道 简单工厂模式是最基本的创建实例相关的设计模式, 但是在真实情况中,有更多复杂的情况需要处理。简单工厂生成实例的类,知道了太多的细节,这就导致这个类很容易出现难维护、灵活性差的问题。

现实中我们要想过好生活,是不太需要也不太可能知道所有细节的。比如说,我们知道猪长什么样子,也知道红烧肉很好吃,但一头猪是通过怎么样的过程变成红烧肉的呢?我们并不需要关注。所以如果将来能生产出这样一台机器,送进去的是猪,出来的就是红烧肉,貌似就好多了。

在我们的程序中,确实存在封装实例创建过程的模式----工厂方法模式,这个模式可以让创建实例的过程封装到工厂类中, 避免耦合,它与简单工厂模式是一个体系的。

简单工厂模式实现

下面我们以简单工厂模式的计算器为例,工厂类和客户端代码如下:

 public class OperationFactory{public static Operation createOperate(String operate){Operation oper = null;switch(operate){case "+":oper = new Add();break;case "-":oper = new Sub();break;case "*":oper = new Mul();break;case "/":oper = new Div();break;}return oper;}}public static void main(String[] args) {Operation oper = OperationFactory.createOperate(strOperate);double result = oper.getResult(numberA,numberB);}

工厂方法模式的实现

如果换成工厂方法模式写这个计算器,代码如下:

public interface IFactory{public Operation createOperation();}public class AddFactory implements IFactory{@Overridepublic Operation createOperation() {return new Add();}} public class SubFactory implements IFactory{@Overridepublic Operation createOperation() {return new Sub();}}public class MulFactory implements IFactory{@Overridepublic Operation createOperation() {return new Mul();}}public class DivFactory implements IFactory{@Overridepublic Operation createOperation() {return  new Div();}}//此时我们的OperationFactory类代码public class OperationFactory{public static Operation createOperation(String operate){IFactory factory = null;Operation oper = null;switch(operate){case "+":factory = new AddFactory();break;case "-":factory = new SubFactory();break;case "*":factory = new MulFactory();break;case "/":factory = new DivFactory();break;}oper = factory.createOperation();return oper;}}

简单方法? 工厂方法?

以前我们说过,如果我们现在需要增加其他运算,比如求x的n次方,或者求以a为底b的对数,这些功能的增加哎,在简单工厂里,我们是先去加求x的n次方运算指数类,然后去更改OperationFactory类,当中加Case语句分支判断即可,现在用了工厂方法,加指数运算没问题,去改OperationFactory类的分支也没问题,但又增加了一个指数工厂类,这不等于不但没有降低难度,反而增加类,把复杂性增加了吗?

简单工厂模式的最大优点在于工厂类中包含必要的逻辑判断,根据客户端的选择条件动态的实例化相关的类,对于客户端来说,去除了与具体产品的依赖。 就像计算器这个实例,让客户端不用管应该用哪个类的实例,只需要把“+”给工厂,工厂就自动的给出了相应的实例,客户端只需要去运算就可以了。但是我们要增加一个X的n次方的操作的话,我们需要给OperationFactory类的方法里加Case条件,这就是说,我们不但对扩展开放了,对修改也开放了,这违背了开放-封闭原则。 也就是说这个OperationFactory类承载了太多功能。

但是在我们上述的工厂方法中好像也没有做到这一点,他比原来多出了四个运算工厂类和一个工厂接口,其实是因为我们上述代码并没有体现工厂模式的优点,举个例子:我们公司原来只有一家工厂,生产四种不同的产品。后来发展比较好,需要增加两种产品放在另一个地方开设新的工厂,新的工厂不应该影响原来工厂的运作。这样我们只需总公司那里再增加一下协调管理部门就好了。

就编程而言,我们应该尽量将长的代码分派切割成小段,再将每一小段‘封装’起来,减少每段代码之间的耦合,这样风险就分散了,需要修改或扩展的难度就降低了。 加减乘除四个类算是一个工厂的产品,不妨叫他们(基础运算工厂)类,现在增加指数、对数运算类,如果算是另一种工厂的两种产品,不妨称他们为‘高级运算工厂’类,就没必要去影响原有的基础运算工厂运作了。

代码实现:

public class Pow extends Operation {public double getResult(double numberA,double numberB){return Math.pow(numberA,numberB);}
}public class Log extends Operation{public double getResult(double numberA,double numberB){return Math.log(numberB)/Math.log(numberA);}
}
public interface IFactory {public Operation createOperation();
}
//基础运算工厂类
public class basicFactory implements IFactory{public Operation createOperation(String operate) {IFactory factory = null;Operation oper = null;switch(operate){case "+" :factory = new AddFactory();break;case "-":factory = new SubFactory();break;case "*":factory = new MulFactory();break;case "/" :factory = new DivFactory();break;}oper = factory.createOperation();return oper;}
}
//高级运算工厂类
public class AdvancedOperationFactory implements IFactory{@Overridepublic Operation createOperation(String operType) {Operation oper = null;switch(operType){case "pow":oper = new Pow();break;case "log":oper = new Log();break;}return oper;}
}public class OperationFactory {public static Operation createOperate(String strOperate) {Operation oper = null;IFactory factory = null;switch (strOperate) {case "+":case "-":case "*":case "/":factory = new basicFactory();break;case "pow":case "log":factory = new AdvancedOperationFactory();break;}oper = factory.createOperation();return oper;}
}

这里我们新的OperationFactory类已经不存在运算子类实例化的代码了,也就是说,在这个代码里,全部都是借口与具体工厂类,并不存在具体的实现,与原来的OperationFactory类对比实例化的过程延迟到了工厂子类中。这里也是依赖倒转原则中的针对接口编程,不要针对实现编程。 注意到关键词 – 延迟到子类

工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类IDE实例化延迟到其子类

工厂方法克服了简单工厂违背开放-封闭原则的缺点,同样保持了封装对象创建过程的优点。工厂方法模式是简单工厂模式的进一步抽象和推广。 由于使用了多态性,工厂方法模式保持了简单工厂模式的优点克服了他的缺点。另外工厂方法模式本质就是对获取对象过程的抽象。

工厂模式好处:

  • 对于复杂的参数构造对象,可以很好的对外层屏蔽代码的复杂性,注意这里是指创建实例的构造对象。
  • 工厂方法模式有很好的解耦能力,这就是针对接口在编程,当我们要修改具体实现层的代码时,上层代码完全不了解实现层的情况,因此不会影响到上层代码的调用。达到解耦目的。

总结

以上就是本文全部内容,本文主要向大家介绍了设计模式中的工厂模式,通过对计算器简单工厂模式代码的修改扩展,一步一步引出工厂方法模式的代码,介绍工厂方法模式的优点和适用性。感谢各位能够看到最后,如有问题,欢迎各位大佬在评论区指正,希望大家可以有所收获!创作不易,希望大家多多支持!

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

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

相关文章

详解 Java 中的 CopyOnWriteArrayList

目录 【1】CopyOnWriteArrayList 简介 【2】核心原理 1.底层数据结构 2.写时复制机制 【3】CopyOnWriteArrayList常用方法及实例 1.添加元素方法 add () 2.获取元素方法 get () 3.删除元素方法remove() 【4】优缺点分析 【5】适用场景 【6】总结 【1】CopyOnWriteAr…

新手SEO优化快速起步教程

本教程专为SEO新手设计,帮助您快速上手优化工作。我们将一步步带您了解基础概念,包括高效挖掘关键词的方法、内容优化的核心技巧,以及网站基础设置的关键步骤。后续还会讲解提升排名的实用策略、如何监控效果并进行调整,确保您能系…

Minecraft图片搜索技巧

以下是更多专注 Minecraft 内容的高质量社区平台,涵盖建筑展示、模组/材质分享、实机截图、艺术创作等方向,按类型分类整理:---一、国际知名综合社区平台 特点 链接 CurseForge 模组/材质/数据包第一仓库,作者更新快,支…

数学建模-非线性规划(NLP)

1-理论知识介绍应用2-基于matlab实现非线性规划1)例1% 清除工作台和命令行 clear;clc; x0[0 0 0]; A [-1 1 -1]; b 0; [x,value] fmincon(f1,x0,A,b,[],[],[],[],nonlfun1) function f f1(x)f x(1)^2x(2)^2x(3)^28; end function [c,ceq] nonlfun1(x)c [x(1)…

人工智能学习:什么是seq2seq模型

一、seq2seq模型 Seq2Seq(Sequence-to-Sequence)模型是一种用于处理序列转换问题的深度学习模型,广泛应用于机器翻译、文本摘要、对话系统、语音识别等领域。Seq2Seq模型的核心思想是通过一个编码器(Encoder)将输入序列编码为一个固定长度的上下文向量(Context Vector),…

生态 | 华院计算与深至科技达成战略合作,携手推动AI+医学影像算法升级迭代

8月25日,华院计算技术(上海)股份有限公司(以下简称“华院计算”)与上海深至信息科技有限公司(以下简称“深至科技”)正式签署战略合作协议。双方将秉持“优势互补、资源共享、战略协同、共同发展…

详解MySQL环境变量配置及其在备份中的应用

正确配置MySQL环境变量是保障数据库稳定运行和高效管理的基础。这些变量涵盖了从内存分配、连接设置到日志行为等方方面面,直接决定了数据库的性能表现和功能特性。对于数据库管理员而言,熟练掌握环境变量的配置,是进行性能调优和故障排查的必…

scikit-learn零基础配置(含python、anaconda)

一、Anaconda环境搭建 1、关于Anaconda Anaconda 是一个非常 popular 的 Python 发行版,它不仅包含了 Python 语言本身,还预装了众多常用的科学计算库,如 NumPy、Pandas、Matplotlib 等,能够极大地方便用户的开发和数据分析工作。…

RAG提示词(日本語版)

RAG提示词(日本語版) System Message # 知能型質問応答アシスタント(RAGシステムプロンプト)## 役割定義 あなたは「知能型質問応答アシスタント」として、提供されたコンテキスト情報に基づいてユーザーの質問に回答する専門的な…

qData 数据中台【开源版】发布 1.0.5 版本,全面提升规则治理、非结构化数据处理与部署体验

2025年9月3日 —— 企业级开源数据中台 qData 开源版 正式发布 1.0.5 版本。本次更新聚焦 规则治理一体化、非结构化数据支持、以及开源版的体验与部署优化,进一步提升规则复用能力、数据接入广度与运维效率,帮助企业和开发者更轻松地构建高质量数据治理…

RecSys:用户行为序列建模以及DIN、SIM模型

引言 在推荐系统中,用户历史行为序列是极其重要的信息源。用户最近的点击、点赞、收藏、转发等行为能够有效反映其即时兴趣,无论是在召回、粗排还是精排阶段,合理利用这些行为序列都能显著提升推荐效果。本文将系统介绍用户行为序列建模的几…

QGIS二次开发01:环境配置-OSGeo4W镜像

写在前面: 本笔记根据多方资料整理而成,旨在为QGIS二次开发提供学习参考。内容仅供交流学习,欢迎共同探讨。 一、关于QGIS QGIS 是一个功能强大的桌面GIS软件本身,为用户提供了图形化界面(GUI)来进行地图制…

对接旅游行业安全需求:旅游安全急救实训室的功能构建与育人目标

随着我国旅游行业的快速发展,游客安全需求日益凸显,安全应急处置能力已成为旅游服务人才的核心竞争力。旅游安全急救实训室作为旅游服务与管理专业中的重要教学场所,其功能构建与育人目标影响人才培养质量与行业安全水平。点击获取方案 一、行…

Typora处理markdown文件【给.md文档加水印】

①文件→偏好设置→外观→打开主题文件夹②在打开的文件夹中放入水印图像③右键点击github.css文件后,点击编辑,进入编辑页面④将代码块中内容粘贴到文件最后 更多效果请自行探索 #write::before {content: "CSDN果子当夜宵:bigxie.blog…

基于单片机的六足机器人控制系统设计

基于单片机的六足机器人控制系统设计摘 要本设计主要是基于单片机的六足机器人控制系统设计,综合分析六足机器人的结构、步态和控制算法,结合云端服务器、WIFI 技术、蓝牙技术、语音识别技术和手势识别技术进行多种控制模式的设计,并提出不同…

RK3568 Trust

文章目录1、环境介绍2、前言3、ARM TrustZone3.1、什么是ARM TrustZone3.2、cpu特权等级3.3、ARM Trusted Firmware4、Rockchip 平台的 Trust4.1、实现机制4.2、启动流程4.3、生命周期4.4、Trust 编译打包流程分析5、总结1、环境介绍 硬件:飞凌ok3568-c开发板 软件…

C语言数据结构——详细讲解《二叉树与堆的基本概念》

C语言数据结构——详细讲解《二叉树与堆的基本概念》前言一、树的基础概念1.1 为什么需要树?1.2 树的定义与结构1.3 树的核心术语1.3 树的核心术语1.4 树的表示方法(孩子兄弟表示法)结构定义为什么用孩子兄弟表示法?1.5 树的实际应…

STAR-CCM+|雷诺数回顾

【1】引言 前序已经学习了K-epsilon湍流模型溯源的基础知识,今天再学习一些更为基础的知识,回顾一下雷诺数ReReRe。 【2】雷诺数定义 雷诺数公式为: ReρvDμRe\frac{\rho vD}{\mu}ReμρvD​ 式中, ρ\rhoρ——流体密度&…

Java中的死锁

锁的合理使用能够保证共享数据的安全性,但是 使用不当也会可能引起死锁。1. 死锁概念 死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉那它们都将无法推进下去,如果系统资源充足,进程的资源请求…

基于STM32F103C8T6的智能家居健康环境监测系统

项目开发背景 随着城市化进程加速和居民生活水平提升,人们对家居环境健康与安全的需求日益增强。现代住宅常因装修材料、密闭空间及外部污染导致甲醛超标、PM2.5浓度升高、温湿度失衡等问题,长期暴露此类环境中易引发呼吸道疾病、过敏反应等健康隐患。传…