理解设计模式之工厂模式

  |   0 评论   |   0 浏览

什么是工厂模式?

  上一篇文章写了关于创建模式之一的单例模式,这篇依然是关于创建模式的,最常用的模式之一,工厂模式。那么到底什么是工厂模式?理解工厂模式的概念很容易,光看工厂两个字就知道了,就是用来生产东西的,工厂模式,可以理解为专门用于生产对象的类,这个类不做其他的,就是生产对象。那么为什么会出现这个模式?我们直接new一个对象不就好了吗?还这么麻烦要专门用一个类来干这个事,不是多此一举么?其实不然,工厂模式提倡了“面向接口”编程的思想,将具体对象的创建跟业务代码解耦,让业务不用关心对象是如何产生的,只需要调用业务对象的接口即可。你想想,如果是new一个对象,然后再初始化这个对象的一些属性,万一哪天对象发生了变化,增加了一个需要初始化的属性,岂不是所有new这个对象的地方都会改一遍?这明显违背了“开闭原则”。因此工厂模式的出现,正是解决对象创建跟业务代码紧耦合这个问题。

工厂模式分类

  工厂模式就是工厂模式,干嘛还要分类呢?初学者可能对这个问题比较疑惑。为啥要分一下类呢?因为工厂这个东西,会随着产品的复杂程度而变化,跟现实世界中的一样,一个简单的工厂流水线不可能生产出种类繁多又很复杂的产品,那么随着产品的变化,工厂的实现也会跟着变化。根据以往查看过的资料来看,工厂模式一共分为三类:简单工厂、工厂方法、抽象工厂。看了一下网上的资料,与以往的总结,简单描述一下自己对这三类工厂实现的理解(只讲原理,不贴代码)。
  简单工厂Simple Factory
  简单工厂,为啥要叫简单工厂?因为简单。我这个工厂只生产一个种类的产品,不生产其他东西,那么这个工厂就是简单工厂。例如假如你开了一个面食厂,专门做包子,生产肉包、菜包和豆沙包(如果你想买馒头,不好意思,到隔壁老王的馒头店去)。结合UML类图理解一下:

1706497488185659392.png

  工厂方法Factory Method
  上面是简单工厂,只能生产一些简单的东西,我就生产这类产品,还是拿面食厂举例,面食厂开张后,生意好了,吃得人越来越多,时间久了大家觉得一个师傅做出来的口味始终是一个味道(想想你们在公司食堂吃了一年的饭菜),这时候突然有人提议,要吃换个口味的包子,但是包子还是肉包、菜包和豆沙包,这个时候怎么办?那么就轮到工厂方法出马了,工厂方法模式生产的产品还是那几样,但是实现者却不一样,实现的产品也不一样,拿面食店举例,假如之前是请老干妈做的包子,那么现在又请了一个老干爹,做口味不一样的包子。结合UML类图理解一下:

1706497569165086720.png

  虽然都是肉包子,但是老干妈的肉包子跟老干爹的肉包子是不一样的口味,因此工厂方法,适合同款产品有多种不同实现的场景。最简单的应用场景如数据库驱动,数据库驱动标准接口是
java.sql.Driver,Driver生产java.sql.Connection对象。实现java.sql.Driver接口的驱动程序有跟多,例如MySQL的驱动与Oracle的驱动,两者生产的Connection对象也分别是基于MySQL数据库的实现和Oracle数据库的实现,但是对于业务开发人员来说,并不用关心到底是Connection是什么实现,我只需要定义好对应数据库的驱动程序即可。
  抽象工厂Abstract Factory
  抽象工厂是在工厂方法之上的又一次扩展,随着产品的复杂度提高,工厂方法以及不能适应更多产品的生产,拿面食工厂举例,时间久了,大家对面食的种类产生了疑惑,为啥没有馒头?要求面食工厂能生产馒头,那么好,现在有两位师傅,一个是老干妈,一个是老干爹,从现在开始让他们生产馒头,我们工厂现在的产品种类有包子和馒头(哪天说不定还有花卷),在这种支持产品种类会有扩展的场景,就需要抽象工厂设计模式来搞定了。集合UML类图理解一下抽象工厂:
1706497657375494144.png

抽象工厂适合产品种类会扩展的场景,但是这种模式也有弊端,在进行产品种类扩展的同时,也会去修改已有的工厂类,添加新的产品生产接口,这个违背了开闭原则,因此要谨慎使用。


标题:理解设计模式之工厂模式
作者:michael
地址:https://blog.junxworks.cn/articles/2018/10/03/1538542421789.html