首页 > 其他分享 >工厂制造细节无须知——工厂方法模式

工厂制造细节无须知——工厂方法模式

时间:2024-09-19 09:19:40浏览次数:9  
标签:运算 模式 工厂 细节 小菜 须知 简单 方法

文章目录

工厂制造细节无须知——工厂方法模式

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

时间:3月19日22点  地点:小菜、大鸟住所的客厅  人物:小菜、大鸟

小菜来找大鸟,说:“简单工厂模式真是很好用呀,我最近好几处代码都用到了该模式。”

"哦!"大鸟淡淡地说道,“简单工厂只是最基本的创建实例相关的设计模式。但真实情况中,有更多复杂的情况需要处理。简单工厂生成实例的类,知道了太多的细节,这就导致这个类很容易出现难维护、灵活性差问题,让人感觉到了不好的味道。”

“知道很多细节不太好吗?”

"现实中,我们要想过好生活,是不太需要也不太可能知道所有细节的。

比如说,我们知道猪长什么样子,也知道红烧肉很好吃,但一头猪是通过怎么样的过程变成红烧肉的呢?养殖、运输、屠宰、销售过程的批发、零售,还有饭店或家里的烹饪过程,对我们来说,都是不需要去了解的。我们去饭店吃饭,只要点了红烧肉,过一会儿它就被送出来了,好吃就行了,你说对不对?"

在这里插入图片描述

“将来如果能生产出这样一台机器,送进去是猪,出来就是红烧肉,那就好了。”

“嘿嘿!这样的机器我不知道是否生产得出来。不过,整个过程也算是一种封装吧。在我们的程序中,确实存在封装实例创建过程的模式——工厂方法模式,这个模式可以让创建实例的过程封装到工厂类中,避免耦合。它与简单工厂模式是一个体系的,你可以去研究一下。”

简单工厂模式实现

“大鸟!我研究了工厂方法模式,但还是不太理解它和简单工厂的区别,感觉还不如简单工厂方便,为什么要用这个模式?到底这个模式的精髓在哪里?”

“那你先把简单工厂模式和工厂方法模式的典型实现说给我听听。”

“哦,简单工厂模式实现是这样的:首先简单工厂模式,若以我写的计算器为例,结构图如下。”

在这里插入图片描述

“工厂类是这样写的。”

在这里插入图片描述

工厂方法模式实现

“那么如果是换成工厂方法模式来写这个计算器,你能写吗?”

“当然是可以,就是因为我写出来了,才感觉好像工厂方法没什么好处!计算器的工厂方法模式实现的结构图是这样的。”

在这里插入图片描述

“先构建一个工厂接口。”

在这里插入图片描述

“然后加减乘除各建一个具体工厂去实现这个接口。”

在这里插入图片描述

“在OperationFactory类中,可以是这样的。”

在这里插入图片描述

"对呀,写得很好。"大鸟说,“工厂方法模式就是这样写的,你有什么问题?”

简单工厂vs.工厂方法

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

"问得好。简单工厂模式的最大优点在于工厂类中包含必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。就像你的计算器,让客户端不用管该用哪个类的实例,只需要把’+'给工厂,工厂自动就给出了相应的实例,客户端只要去做运算就可以了,不同的实例会实现不同的运算。

但问题也就在这里,如你所说,如果要加一个’求x的n次方(xn)'的功能,我们需要给OperationFactory类的方法里加’Case’的分支条件。目前来看,这个OperationFactory类,承载了太多功能,这可不是好办法。这就等于说,我们不但对扩展开放了,对修改也开放了,这样就违背了什么原则?"

“哦,是的,违背的是开放-封闭原则。”

“对,也就是说,我们加减乘除运算的部分已经相当成熟了,但是因为增加新的功能,就要去改已经很成熟的类代码,这就好比很多鸡蛋放在了一个篮子里,这是很危险的。”

“那么工厂方法模式,就可以解决这个问题吗?我感觉我本来是4个运算类,1个工厂类,共5个类,现在多出了4个运算工厂类和1个工厂接口,问题依然没有解决。”

“哈哈,那是因为你没有真的理解工厂方法。举一个例子,我们公司本来只有一家工厂,生产四种不同的产品。后来发展得特别好,需要增加新的两种产品放在另一个地方开设新的工厂。新的工厂不应该影响原有工厂的正常工作,你说怎么办?”

“新工厂建在别的地方,应该不影响原有的工厂运作,最多就是建好后,总公司那里再增加一些协调管理部门就好了。”

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

“哦!我明白你的意思了。并不是要去创建加法工厂、减法工厂这样的类,而是将加减乘除用一个基础工厂来创建,现在增加了新的产品,又不想影响原有的工厂代码,于是就扩展一个新的工厂来处理。我马上改。”

“下面是原有的工厂结构,加减乘除运算已经非常稳定,尽量不要去改变它们。”

在这里插入图片描述

“增加了一种新的工厂和两种新的运算类(以后可以扩展更多的高级运算,比如正余弦、正余切等),不要影响原有的代码和运作。”

在这里插入图片描述

“增加两个运算类。”

在这里插入图片描述

“基础运算工厂类,此类已经比较成熟稳定,实现后应该封装到位,不建议轻易修改。”

在这里插入图片描述

“高级运算工厂类,也许还有扩展产品的可能。”

在这里插入图片描述

“左侧新的OperationFactory类与右侧原来的OperationFactory类对比。”

在这里插入图片描述

"你或许会发现,新的OperationFactory类已经不存在运算子类实例化的代码了。也就是说,在这个代码里,全部是接口与具体工厂类,并不存在具体的实现,与原来的OperationFactory类对比,实例化的过程延迟到了工厂子类中。"大鸟说道,"不过新的OperationFactory类依然存在’坏味道’,当

增加新的运算子类时,它本身也是需要更改的,这个先放在一边,以后可以解决。"

“Perfect!我明白了。这就是前面提到的针对接口编程,不要对实现编程吧?”

“是的。我们来看工厂方法的定义。注意关键词——延迟到子类。”

工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。[DP]

在这里插入图片描述

“我们讲过,既然这个工厂类与分支耦合,那么我就对它下手,根据依赖倒转原则,我们把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法。然后,所有的要生产具体类的工厂,就去实现这个接口,这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口具体生成对象的工厂。每个工厂可以有多个不同产品,而工厂之间,又是相对隔离封装状态。这样过去已经比较完善的工厂和产品体系,就不需要再去改动它们,而另外需要变更的代码,完全可以通过扩展来变化,这就完全符合了开放-封闭原则的精神。”

“哦,工厂方法从这个角度讲,的确要比简单工厂模式来得强。”

“严格来说,是一种升级。当只有一个工厂时,就是简单工作模式,当有多个工厂时,就是工厂方法模式。类似由一维进化成了二维,更强大了。”

商场收银程序再再升级

大鸟:“还记得我们前面不断改进过的商场收银程序吗?最后一版是增加了装饰模式。”

小菜:“我记得。后面已经改得非常漂亮了,能适应各种变化。”

大鸟:“那你看看下面这段代码有优化的空间吗?”

在这里插入图片描述

小菜:“以前不觉得,现在发现确实是太多的new实例了,尤其是5和6,装饰模式的使用,在这个CashContext类中,显得特别的复杂。”

大鸟:“是的,那么学完了工厂方法模式,你有没有改进的想法?”

小菜:“我想想。你的意思是创建几个工厂类来处理这些new?”

大鸟:“问题是,你打算创建几个工厂类呢?”

小菜:“从上面的代码来看,我感觉至少应该有原价销售类、打折类、满减返利类、先打折再满减类和先满减再打折类,一共五个工厂类。”

大鸟:“尝试抽象一下,能不能合并一部分呢?”

小菜:“我想想。好像原价类,可以想象成打折的参数为1的打折类。但打折与满减返利好像合并不了。”

大鸟:“它俩是合并不了,但先打折后满减类能不能涵盖它们俩?”

小菜:“我懂了。如果有’先打折后满减类’存在,那它应该有三个初始化参数:折扣值、满减条件、满减返利值,那么打折类,其实就是满减返利值条件为0的情况,另外满减类,就相当于折扣参数为1的情况。”

大鸟:“非常好!所以最终只会抽象成几个工厂类?”

小菜:“那就只需要’先打折再满减’和’先满减再打折’两个工厂类了。”

大鸟:“赶紧去实现一下吧。”

简单工厂+策略+装饰+工厂方法

在这里插入图片描述

小菜:“我的实现方法,首先原有的ISale、CashSuper、CashNormal、CashReturn、CashRebate等类都不变。”

“增加IFactory接口。”

在这里插入图片描述

“增加实现IFactory接口的两个类,'先打折再满减’类和’先满减再打折’类,其中红框部分代码为装饰模式的实现。”

在这里插入图片描述

“有了上面的这些准备后,CashContext类就简单多了,它针对的是ISale接口、IFactory接口编程,然后两个工厂类,对于各个打折满减算法CashSuper、CashNormal、CashReturn、CashRebate等具体类一无所知。实现了松耦合的目的。”

在这里插入图片描述

大鸟向小菜竖起了大拇指。

小菜:“我感觉工厂方法克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点。

大鸟:“说得好,它们都是集中封装了对象的创建,使得要更换对象时,不需要做大的改动就可实现,降低了客户程序与产品对象的耦合。工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。就像生活中,凡是在基层工作过的人都知道,具体事情做得越多,越容易犯错误。相反,如果做官做得高了,说出的话就会比较抽象、笼统,很多时候犯错误的可能性反而就越来越小了。”

小菜:“工厂方法模式是不是本质就是对获取对象过程的抽象?”

大鸟:“说得非常对,就是这样。工厂方法的好处有这么几条:第一,对于复杂的参数的构造对象,可以很好地对外层屏蔽代码的复杂性,注意是指创建新实例的构造对象。比如说我们用了’先打折再满减’类工厂,其实就屏蔽了装饰模式的一部分代码,让CashContext不再需要了解装饰的过程。**第二,很好的解耦能力。**这点刚才你也说了,这就是针对接口在编程。当我们要修改具体实现层的代码时,上层代码完全不了解实现层的情况,因此并不会影响到上层代码的调用,这就达到了解耦的目的。”

小菜:“对了。你说这还不是最佳的做法?那应该如何做呢?还有就是这样还是没有避免修改客户端的代码呀?”

大鸟:“哈,之前我就提到过,利用’反射’可以解决避免分支判断的问题。不过今天还是不急,等以后再谈。”

如果对你有帮助,就一键三连呗(关注+点赞+收藏),我会持续更新更多干货~~

标签:运算,模式,工厂,细节,小菜,须知,简单,方法
From: https://blog.csdn.net/m0_63526467/article/details/142351152

相关文章

  • 大数据-128 - Flink 并行度设置 细节详解 全局、作业、算子、Slot
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(正在更新!)章节内容上节我们完成了如下的内容:ManageOperatorStateStateBackendCheckpoint......
  • 精品PPT | 离散制造行业智能工厂总体解决方案
    一、建设背景离散制造业,包括机械制造业、汽车制造业和家电制造业等,其生产过程涉及多个不连续的工序,产品通常由多个零件装配而成。这类行业面临的挑战包括品种多、批量小、订单变化快、临时插单频繁以及外协件管理困难等问题,这些特点使得生产管理复杂且难以预测。传统的管理方式过度......
  • 构建数字化工厂的智能制造-数字化智能制造(82页PPT下载)
    方案介绍:智能制造是指通过信息技术的应用,将传统制造业转变为基于数据和智能化决策的现代化制造方式。它以数字化技术为基础,实现了生产流程的数字化、信息化和自动化。智能制造不仅提升了生产效率和质量,还促进了资源的有效利用和环境保护,实现了绿色生产的目标。构建数字化工厂的智能......
  • vulnhub(9):sickos1.2(深挖靶机的各个细节、文件管道反弹shell详解、base64编码反弹shell
    端口nmap主机发现nmap-sn192.168.148.0/24​Nmapscanreportfor192.168.148.131Hostisup(0.00020slatency).​131是新出现的机器,他就是靶机nmap端口扫描nmap-Pn192.168.148.131-p---min-rate10000-oAnmap/scan扫描开放端口保存到nmap/scan下​......
  • 【Java】若依(ruoyi)——7.代码生成(二)细节操作
    之前我们已经学习了代码生成的基础使用:https://www.cnblogs.com/luyj00436/p/18398248。即创建数据库并根据三种数据结构生成代码。1.基本信息和生成信息 前缀可以在配置表设置默认配置。单应用在resources目录下的application.yml,多模块ruoyi-generator中的resources目录下......
  • spring工厂模式
    https://blog.csdn.net/qq_57005976/article/details/134367016工厂模式工厂模式的三种形态:工厂模式是解决对象创建问题的属于创建型设计模式,Spring框架底层使用了大量的工厂模式第一种:简单工厂模式是工厂方法模式的一种特殊实现,简单工厂模式又叫静态工厂方法模式不属于23种......
  • 简单工厂模式
    简单工厂模式简单工厂模式(SimpleFactoryPattern)是一种创建型设计模式,通过一个工厂类来决定实例化哪一个类的对象。它是最常见的设计模式之一,主要用于将对象的创建与使用分离,减少代码重复,提高代码的可维护性。特点工厂角色:负责创建具体产品类的实例,通常是一个包含静态方法的......
  • 抽象工厂模式
    抽象工厂模式抽象工厂模式(AbstractFactoryPattern)是一种创建型设计模式,它提供一个接口,用于创建一系列相关或互相依赖的对象,而无需指定它们的具体类。抽象工厂模式常用于需要创建一组相关或依赖对象的场景,确保这些对象在不同的环境中可以协同工作。特点抽象工厂:定义了一组创......
  • 设计模式---- 工厂模式
    工厂模式工厂模式是一种创建型设计模式,它的主要目的是将对象的创建过程与对象的使用过程分离。工厂模式通过引入工厂类或者工厂方法,隐藏对象创建的复杂性,使得代码更加灵活、可扩展。工厂模式的使用场景主要在于:当我们需要对创建的对象进行封装或延迟创建时,工厂模式是一个很好的选......
  • 小张游戏厅售前须知(20s阅读完成)
    1.发货形式是什么?发您网盘链接,保存下载后解压即玩,无需安装2.是否通过steam平台?不通过steam平台,和正版唯一区别是不能联机,为单机版3.发货网址是什么? link3.cc/xiaozhangzahuopu(显示404打不开的可以复制到浏览器打开)4.后续包更新吗?后续包更新的,更新第一时间会在群内通知......