【设计模式】实战中理解工厂方法

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

1. 背景

项目需求:开发一个能够拥有加减乘除功能的计算器
技术选型:Java Swing编程
在这里插入图片描述
原型图大致如上所示

2. 代码优化

2.1 第一版

加法按钮的后台代码,如下
在这里插入图片描述
分析
在这里插入图片描述
看完上面的代码,思索如下。

  1. 图中画红框的地方很明显,就已经写死了,只能获取两个固定组件的值,也只能调用加法,如果我此时需要一个减法的按钮,那么就要把加法的代码粘贴过去,然后修改一下逻辑。
  2. 那么我需要一个乘法呢?除法呢?或者一个更加高级的算法?,复制粘贴修改虽然是用的比较多的一种方式,但是它的缺点也是很明显的,复制粘贴修改很容易修改出错,而且也不容易理解。
  3. 更有甚者,当这种加法不满足我的需求,我需要一个高级加法,我就需要去修改加法的代码,这样就违背了开闭原则了。那么怎么优化呢?

另外,如下图,加法和加法逻辑在一起,另外的页面需要加法,也是粘贴过去吗?
在这里插入图片描述

抽象

在这里插入图片描述
我们可以把加法按钮的方法和加法逻辑拆开,形成类似于现在流行的前后端分离的模式,界面只负责

调用按钮的方法,具体的实现方法由后端提供

按钮方法
在这里插入图片描述

封装

加法运算类
在这里插入图片描述
这样在其他就把加法运算类抽象出来了,其他加法按钮也就可以调用这个方法了

假如有一天你想把加法按钮的加法运算变成NB加法运算

在这里插入图片描述
除了改代码,还有什么选择吗?

先举例说明一下开闭原则的重要性
在这里插入图片描述
上述问题就是由于违背开闭原则导致的,修改以前的代码看似没有问题,但是由于这个时候随着代码逻辑越来越复杂,代码耦合性比较强,一旦修改,当前问题可能解决了,但是也很容易导致引发其他问题

从上面对开闭原则的例子我们明白了,为什么不可以违背开闭原则,那么怎么在不修改代码的情况下,才能切换算法呢?

AddOperation addOperation=new AddOperation ();
必须用AddOperation 

咱们先解决等号左边的问题,就是先将AddOperation 抽象为运算类,这也叫做依赖抽象
在这里插入图片描述
此时增加NB加法运算类,和Operation运算类,此时Operation是父类,其他的运算都去继承他
在这里插入图片描述

多态

此时左边就可以切换成Operation operation,由于Operation是父类,根据多态的特性,父类的引用可以指向子类的对象,那么此时等号左边就不需要动了,只要修改等号右边的代码就可以了
在这里插入图片描述

反射

但是你可能又要说了,那不是还是修改代码了嘛,不要着急,这个时候我们可以利用反射,通过修改配置文件,就可以实现不修改代码就可以切换运算方法
在这里插入图片描述

简单工厂

加入我要制造一辆汽车
在这里插入图片描述
你是不是要先new一个汽车类,然后new一个底盘类,然后new一个轮胎类,等等
在这里插入图片描述
汽车是要批量化生产的,难道你每次生产汽车都要这么new一遍吗?

但是如果有流水线工厂就不一样的
在这里插入图片描述
此时new对象的职责可以交给工厂来办
在这里插入图片描述
加法减法等等运算类就可以放到工厂中,你要什么算法由工厂来给你new
在这里插入图片描述
此时的UML
在这里插入图片描述
但是这个时候有一个问题,简单工厂中有的算法你可以调用,但是没有的呢?
在这里插入图片描述
接下来新增一个算法的流程就变成了这样
在这里插入图片描述
那有什么办法解决呢?

工厂方法

你比如你想要一个特殊的算法,简单工厂没有办法满足你,工厂方法的解决办法就是给你一个凭据
在这里插入图片描述
你需要什么样的工厂都可以调用IFactory工厂
在这里插入图片描述
然后看如下代码
增加一个加法工厂实现了工厂接口
在这里插入图片描述
Addfactory可以放到配置文件中,此时需要一个什么加法工厂就传进去什么加法工厂就可以了
在这里插入图片描述
因为你传的是Addfactory,所以
在这里插入图片描述
所以此时的factory.createOperation();调用的就是Addfactory的createOperation的方法,返回的就是加法工厂
在这里插入图片描述
这就实现了工厂方法

猜你喜欢

转载自blog.csdn.net/yujing1314/article/details/106728769