当前位置:首页 > 技术知识 > 正文内容

简单学设计模式——工厂模式_工厂模式原理

maynowei9个月前 (09-29)技术知识142

要说23种设计模式中,工厂模式无疑是最简单的设计模式之一。虽然工厂模式简单,基本上刚入门的新手都能看得懂,但是能用好也是不简单的,或者说是能够结合业务在实际的项目中使用是非常不易的,因为在实际的开发中,可以使用工厂模式的地方很容易被“if……else……”代替,而不是用工厂模式来消除“if……else……”。举个例子——

假如有一个自动生产饮料果汁的售货机,会根据客户输入的果汁类型来生产果汁给客户的场景,相信大部分人的代码都如下(其中FruitJuice是果汁的父类,这里分别实现了苹果汁AppleJuice、柠檬汁LemonJuice以及菠萝汁PineappleJuice)

输入“LemonJuice”

这样实现是一点问题都没有的,输入“LemonJuice”然后就能得到柠檬汁,完成能够满足当前的需求;

但是如果我们再对未来业务的考虑,这样实现真的好吗?

事实上这样的实现是不好的实现,虽然能够完成功能需求。这里简单指出其实现不足,一是,如果其他类似的场景也是需要生产果汁,但是果汁的种类跟这边的场景不一样,无法重构成一个方法,是不是每次进行实例化前再一次这样“if……else…… ”去判断再实例化对应的实现类;二是从业务角度来说,果汁种类很多,未来要添加新的果汁类型的话,需要再次在业务的代码中添加“if……else……”,如果项目中类似要创建对应果汁类型的代码有多个地方,那必须修改多个地方,不利于维护和扩展。

那我们应该如何优化?

首先我们创建一个类FruitJuiceFactory,专门用来生产果汁的,所有的果汁生产都经过此类的方法来获得

最后业务代码改造成如下:

然后我们对比一下改造前后的差别:

可以看出改造后的代码简洁了不少,但有人可能有疑问,这不是把创建“果汁”对象的“if……else……”代码迁移到FruitJuiceFactory里面去了,代码量和“if……else……”还是没有减少,还多创建了一个工厂类,这样真的有必要吗?

答案是:真的有必要!

首先,如果是在实际的项目中,类似使用“果汁”对象的代码有可能不止这一处,如果我们将生产果汁对象的方法都集中到工厂类中,封装统一使用工厂类来创建管理,这样才符合我们的设计原则,就不用类似再开一个新的果汁饮料实体店,然后再“if……else……”再去判断实现一遍,如果这样代码冗余很多,很不利于维护。

其次,软件开发有一个亘古不变的真理,那就是change(变化),不管一个软件设计得有多好,总需要成长和改变的,否则,软件就会“死亡”!因此,一个软件好的设计原则是,找出软件中可以能需要变化的部分,将它们封装独立出来,不要和那些不需要变化的代码混在一起。在上述的例子中,从业务发展来说,我们明显能够了解到果汁的实现类会有变化,有可能实现类越来越多,比如加入葡萄汁、橙汁等,这个时候我们只需要在变化的工厂类中添加新的实现就好,而不用在一些不需要变动的业务代码去进行改动,而这里的较大可能变化就是果汁实现类,不变的是业务逻辑,所以把果汁对象的创建过程封装起来是一个较好的设计实现。

总结

工厂模式简大部分的应用场景跟上述例子类似,就是传入一个具有识别性的参数,然后产生对应的实现类对象,在实际开发中可能会有一些变种,但核心的思想就是通过一个统一的类方法去管理某类型下对象的创建,实现软件中的“变化”和“不变”高内聚低耦合。

相关文章

Objective-c单例模式的正确写法「藏」

单例模式在iOS开发中可能算是最常用的模式之一了,但是由于oc本身的语言特性,想要写一个正确的单例模式相对来说比较麻烦,这里我就抛砖引玉来聊一聊iOS中单例模式的设计思路。关于单例模式更多的介绍请参考...

Flutter 之 ListView(flutter框架)

在 Flutter 中,ListView 可以沿一个方向(垂直或水平方向)来排列其所有子 Widget,常被用于需要展示一组连续视图元素的场景ListView 构造方法ListView:仅适用于列表中...

webview 渲染机制:硬件加速方式渲染的Android Web

webview 渲染是什么?webview 渲染是用于展现web页面的控件; webview 可以内嵌在移动端,实现前端的混合式开发,大多数混合式开发框架都是基于 webview 模式进行二次开发的w...

Android主流UI开源库整理(android完整开源项目)

前言最近老大让我整理一份 Android主流UI开源库 的资料,以补充公司的Android知识库。由于对格式不做特别限制,于是打算用博客的形式记录下来,方便查看、防丢并且可以持续维护、不断更新。标题隐...

如何正确理解Java领域中的并发锁,我们应该具体掌握到什么程度?

苍穹之边,浩瀚之挚,眰恦之美; 悟心悟性,善始善终,惟善惟道! —— 朝槿《朝槿兮年说》写在开头对于Java领域中的锁,其实从接触Java至今,我相信每一位Java Developer都会有这样的一个...

Qt QWaitCondition 的正确使用方法

简单用法QWaitCondition 用于多线程的同步,一个线程调用QWaitCondition::wait() 阻塞等待,直到另一个线程调用QWaitCondition::wake() 唤醒才继续往...