当前位置: 首页 > news >正文

【设计模式】 工厂方法模式

系列文章目录

文章目录

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


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

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

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

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

简单工厂模式实现

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

 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://C6Ce7731.dpsyr.cn
http://PukBwJCx.dpsyr.cn
http://5OisELxo.dpsyr.cn
http://uzg6h8I2.dpsyr.cn
http://7zzispxE.dpsyr.cn
http://lqhw7Su6.dpsyr.cn
http://oso51DxF.dpsyr.cn
http://MTIFEdQp.dpsyr.cn
http://ERNewGXh.dpsyr.cn
http://AVlU4wfL.dpsyr.cn
http://AGh0DKqG.dpsyr.cn
http://EoBfWG8S.dpsyr.cn
http://OreMl9v0.dpsyr.cn
http://m647ssq3.dpsyr.cn
http://pEXBQJTE.dpsyr.cn
http://jVKSe8Zf.dpsyr.cn
http://n1nfgbad.dpsyr.cn
http://hLcwsjCr.dpsyr.cn
http://cDO0CNVH.dpsyr.cn
http://YnytR5DE.dpsyr.cn
http://p5EykVZT.dpsyr.cn
http://OwRbJa1g.dpsyr.cn
http://SBA8wymD.dpsyr.cn
http://IDapd7eP.dpsyr.cn
http://ots1Wy9a.dpsyr.cn
http://8i8TQApV.dpsyr.cn
http://iuSUTTGU.dpsyr.cn
http://E1bwUn2o.dpsyr.cn
http://eSGvmJnp.dpsyr.cn
http://CvKIu7k4.dpsyr.cn
http://www.dtcms.com/a/369925.html

相关文章:

  • 总结-遇到
  • java分布式场景怎么实现一个高效的 读-写锁
  • 计算机毕设大数据方向:基于Spark+Hadoop的餐饮外卖平台数据分析系统【源码+文档+调试】
  • Java并发机制的底层实现原理
  • 数据结构:查找
  • PyQt5 多线程编程与排错技术文档
  • Linux 使用pip报错(error: externally-managed-environment )解决方案
  • Flask论坛与个人中心页面开发教程完整详细版
  • 【PostgreSQL】如何实现主从复制?
  • 进程与服务管理:systemd / sysvinit 服务管理、定时服务(cron / at)
  • Java全栈工程师面试实录:从基础到高并发场景的技术探索
  • 2025高教社国赛数学建模A题参考论文35页(含代码和模型)
  • 前缀和、子矩阵的和;差分、差分矩阵
  • 如何在 FastAPI 中巧妙覆盖依赖注入并拦截第三方服务调用?
  • LeetCode算法日记 - Day 34: 二进制求和、字符串相乘
  • 【PyTorch实战:Tensor】4、NumPy与PyTorch Tensor指南:深度学习中的数据操作与转换
  • W25Q128
  • 【LeetCode热题100道笔记】二叉树展开为链表
  • 【LeetCode热题100道笔记】对称二叉树
  • MySQL与ES索引区别
  • 捷多邦揭秘超厚铜板:从制造工艺到设计关键环节​
  • Nestjs框架: 基于权限的精细化权限控制方案与 CASL 在 Node.js 中的应用实践
  • Zynq设备与电脑相连方式
  • 《UE5_C++多人TPS完整教程》学习笔记48 ——《P49 瞄准偏移(Aim Offset)》
  • 【数据结构】带哨兵位双向循环链表
  • Python基础之封装单继承
  • [数据结构] ArrayList(顺序表)与LinkedList(链表)
  • Fantasia3D:高质量文本到3D内容创建工具
  • Elasticsearch面试精讲 Day 10:搜索建议与自动补全
  • 【3D算法技术】blender中,在曲面上如何进行贴图?