什么是工厂模式?
上一篇文章写了关于创建模式之一的单例模式,这篇依然是关于创建模式的,最常用的模式之一,工厂模式。那么到底什么是工厂模式?理解工厂模式的概念很容易,光看工厂两个字就知道了,就是用来生产东西的,工厂模式,可以理解为专门用于生产对象的类,这个类不做其他的,就是生产对象。那么为什么会出现这个模式?我们直接 new 一个对象不就好了吗?还这么麻烦要专门用一个类来干这个事,不是多此一举么?其实不然,工厂模式提倡了“面向接口”编程的思想,将具体对象的创建跟业务代码解耦,让业务不用关心对象是如何产生的,只需要调用业务对象的接口即可。你想想,如果是 new 一个对象,然后再初始化这个对象的一些属性,万一哪天对象发生了变化,增加了一个需要初始化的属性,岂不是所有 new 这个对象的地方都会改一遍?这明显违背了“开闭原则”。因此工厂模式的出现,正是解决对象创建跟业务代码紧耦合这个问题。
工厂模式分类
工厂模式就是工厂模式,干嘛还要分类呢?初学者可能对这个问题比较疑惑。为啥要分一下类呢?因为工厂这个东西,会随着产品的复杂程度而变化,跟现实世界中的一样,一个简单的工厂流水线不可能生产出种类繁多又很复杂的产品,那么随着产品的变化,工厂的实现也会跟着变化。根据以往查看过的资料来看,工厂模式一共分为三类:简单工厂、工厂方法、抽象工厂。看了一下网上的资料,与以往的总结,简单描述一下自己对这三类工厂实现的理解(只讲原理,不贴代码)。
简单工厂 Simple Factory
简单工厂,为啥要叫简单工厂?因为简单。我这个工厂只生产一个种类的产品,不生产其他东西,那么这个工厂就是简单工厂。例如假如你开了一个面食厂,专门做包子,生产肉包、菜包和豆沙包(如果你想买馒头,不好意思,到隔壁老王的馒头店去)。结合 UML 类图理解一下:
工厂方法 Factory Method
上面是简单工厂,只能生产一些简单的东西,我就生产这类产品,还是拿面食厂举例,面食厂开张后,生意好了,吃得人越来越多,时间久了大家觉得一个师傅做出来的口味始终是一个味道(想想你们在公司食堂吃了一年的饭菜),这时候突然有人提议,要吃换个口味的包子,但是包子还是肉包、菜包和豆沙包,这个时候怎么办?那么就轮到工厂方法出马了,工厂方法模式生产的产品还是那几样,但是实现者却不一样,实现的产品也不一样,拿面食店举例,假如之前是请老干妈做的包子,那么现在又请了一个老干爹,做口味不一样的包子。结合 UML 类图理解一下:
虽然都是肉包子,但是老干妈的肉包子跟老干爹的肉包子是不一样的口味,因此工厂方法,适合同款产品有多种不同实现的场景。最简单的应用场景如数据库驱动,数据库驱动标准接口是
java.sql.Driver,Driver 生产 java.sql.Connection 对象。实现 java.sql.Driver 接口的驱动程序有跟多,例如 MySQL 的驱动与 Oracle 的驱动,两者生产的 Connection 对象也分别是基于 MySQL 数据库的实现和 Oracle 数据库的实现,但是对于业务开发人员来说,并不用关心到底是 Connection 是什么实现,我只需要定义好对应数据库的驱动程序即可。
抽象工厂 Abstract Factory
抽象工厂是在工厂方法之上的又一次扩展,随着产品的复杂度提高,工厂方法以及不能适应更多产品的生产,拿面食工厂举例,时间久了,大家对面食的种类产生了疑惑,为啥没有馒头?要求面食工厂能生产馒头,那么好,现在有两位师傅,一个是老干妈,一个是老干爹,从现在开始让他们生产馒头,我们工厂现在的产品种类有包子和馒头(哪天说不定还有花卷),在这种支持产品种类会有扩展的场景,就需要抽象工厂设计模式来搞定了。集合 UML 类图理解一下抽象工厂:
抽象工厂适合产品种类会扩展的场景,但是这种模式也有弊端,在进行产品种类扩展的同时,也会去修改已有的工厂类,添加新的产品生产接口,这个违背了开闭原则,因此要谨慎使用。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于