定义
简单工厂模式 (Simple Factory Pattern): 定义一个工厂类, 它可以根据参数的不同返回不同类的实例, 被创建的实例通常都具有共同的父类. 因为在简单工厂模式中用于创建实例的方法是静态(static) 方法, 因此简单工厂模式又被称为静态工厂方法 (Static Factory Method) 模式, 它属于类创建型模式.
通俗理解
现实生活中的工厂, 大家想到的是, 在流水线上坐着的栩栩动人的工厂妹妹, 在仓库门口搬货有着六块腹肌的工厂哥哥, 还有... ... 其实工厂重要的不仅仅是人, 还有工厂生产的产品. 我们有许多生活用品都是工厂生产的, 我们的杯子, 是通过塑胶厂压模生产出来的; 我们的喝的牛奶, 是通过牛奶厂厂自动化消毒, 包装过的产品; 我们看的书籍, 是通过印刷厂印刷得到的.
现在有很多人, 抱怨工厂的自动化生产, 给他们带来了失业, 下岗, 使他们四肢不勤, 五谷不分, 很多人都向往着桃花源那样的农家生活, 但是想象一下, 如果没有了工业化, 我们的生活会是怎么样的?
就举我们的看的书为例子, 一本书, 由作家构思到出版印刷, 然后买到读者的手上, 大概有这样的一个过程: 构思, 书写, 校验, 排版, 印刷, 装订, 包装, 销售. 这八个过程还是一个简略的过程, 实际上会复制得多. 如果是工业化之后的社会, 我们只需要去书店买这样的一本书就可以了, 但是如果一手操劳的话. 我们得先培养一批作家, 让他们饱读诗书, 让他们具备很好的想象力; 然后要去伐木, 将木头打成碎屑, 漂白, 做成白纸; 去提取碳, 做墨水... ... 然后我们要雕刻印刷版... ... 这真的是一个繁重的过程, 而且效率极其低下.
有什么办法? 很简单嘛. 各个专业的人做专业的事情, 造纸厂造纸, 墨水厂做墨水, 印刷厂印刷(单一功能原则, 依赖倒转原则). 普通的用户不需要关心这个过程, 读者能够在书店买到这本书(迪米特法则).
简单工厂就是这样, 工厂生产一批差不多的产品(例如杯子厂生产方的, 圆的杯子), 我不需要知道其中的过程, 我只需要告诉工厂, 我需要什么产品, 工厂就会按照我的需求, 给我生产相对应的产品.
业务
渣渣程序
我们每个人都需要杯子用来喝水, 那么我们拿杯子喝水的这个过程, 可以由拿杯子, 装水, 喝水这三个过程组成, 我们可以写出下面这样的程序.
杯子
- public abstract class BaseCup {
- public abstract String cupType();
- }
- public class CircleCup extends BaseCup {
- @Override
- public String cupType() {
- return "这是一个圆杯子";
- }
- }
- public class SquareCup extends BaseCup {
- @Override
- public String cupType() {
- return "这是一个方杯子";
- }
- }
调用方
- public class Human {
- public static void main(String[] args) {
- BaseCup cup = new CircleCup();
- System.out.println(cup.cupType());
- }
- }
上面的程序, 是实现了功能, 但是存在着一系列的问题, 第一: 调用方必须知道有什么继承了 BaseCup, 他能用什么杯子. 第二: 杯子的创建过程并没有建立起来, 我们程序的例子只是使用了一个无参的构造函数, 那如果我们使用了有参数的构造函数呢? 我们是不是需要传入杯子的大小, 颜色, 形状, 我们才能使用到杯子? 其实对于用户来讲, 他们只是需要一个杯子而已.
优化
既然我们进入工业化了, 那么我们就用工厂来生产杯子, 而不是我们自己来生产杯子. 我们可以告诉工厂, 我们需要什么类型的杯子, 然后使用工厂生产的杯子就可以了.
类图
image
程序
工厂类
- public class CupFactory {
- public static BaseCup buildCup(String type) {
- switch (type){
- case "circle": return new CircleCup();
- case "square": return new SquareCup();
- default:return null;
- }
- }
- }
调用方
- public class Human {
- public static void main(String[] args) {
- BaseCup cup2 = CupFactory.buildCup("square");
- System.out.println(cup2.cupType());
- }
- }
优点
实现对象的创建和使用分离. 使用工厂创建对象, 调用方只需要使用就可以了.
创建对象时候提供一些默认初始化的参数. 不需要调用方一个个去设置.
可以使用 Spring 的配置文件, 或者其他配置文件, 替代 switch 代码段, 提高灵活性.
缺点
实例化的大旗由工厂扛, 工厂倒闭了, 大家都不能用.
一个类型就得建一个类, 类多了, 系统就复杂了.
增加新的类型要在工厂上加代码, 工厂后面会变得好复杂.
工厂无法继承, 没有子工厂的概念, 全都是大包干.
应用场景
工厂生产的类型比较少的.
调用方不关心类是如何生产的.
来源: http://www.jianshu.com/p/a62f211b2ef8