工厂模式属于创建型模式,它提供了一种更加优雅的创建对象的方式,也是最常见的设计模式之一!
引
用户需要到 ”交通工具生产车间“ 去获取一种交通工具,用户可能要 “汽车“ 或 ”自行车“ 甚至是 “飞机”等。。。作为生产车间,只需要告诉用户一个获取其想要的交通工具的方法即可,至于交通工具是如何生产出来,用户并不需要去关心。
正文
简单工厂模式(静态工厂方法模式)
用户可以使用工厂类提供的 get 静态方法并传入的不同参数,从而获取不同的实例,这些被创建的实例通常都具有共同的父类:
实现起来也很比较容易,共同父类:
1 | public abstract class Transportation { |
汽车、自行车、飞机等等实现类:
1 | public class Car extends Transportation { |
工厂类:
1 | public class TransportationFactory { |
测试:
1 | public static void main(String[] args) { |
这种方式简单方便,JDK 中也有很多应用,例如:DateFormat
提供了 get(LocaleProviderAdapter adapter, int timeStyle, int dateStyle, Locale loc)
去根据参数去创建不同的实例。。
但是这种方式有一个致命的缺点就是不够灵活!每新增一种交通工具,都需要修改工厂类的方法,这就违背了程序设计中的开闭原则!
工厂模式
可以看作是一种简单工厂模式的再抽象,在简单工厂模式中每个交通工具都有一个共同父类,但是都通过一个统一的大工厂去创建;
而工厂模式中,在之前简单工厂模式的基础上,工厂类本身也需要分成不同的子工厂类,每种子工厂类去创建其具体的交通工具,且都共同继承自的同一个大工厂父类:
按照惯例,找一个 JDK 中的例子:Collection 接口看作是一个工厂抽象类,其中有抽象方法 iterator()
用于创建迭代器,很多类都实现了这个接口,例如 ArrayList 实现了接口作为子工厂,会 new 一个 Itr 类对象,这个 Itr 类作为具体的”产品”也同样有一个迭代器父类 Iterator;除此之外 LinkedList 也可以 new 一个具体产品 ListItr 类对象,这个类的父类也同样是 Iterator。等等。。。
概括来说,就是定义一个用于创建对象的接口,让其子类决定实例化哪个类。工厂模式优点是将一个类的实例化延迟到其子类。
将简单工厂的例子改造为工厂模式后,类图:
抽象工厂模式
抽象工厂模式可以看作是工厂模式的又一次扩展,直接看将工厂模式改造成抽象工厂模式后的类图:
在之前的工厂模式,一个工厂父类(或工厂接口)的所有子工厂都是生产同一大类的子类,那么我们只要给这个工厂父类(或接口)增加可以生产其大类抽象方法,并让其所有的子工厂都各自实现这个抽象方法,就可以做到让一个工厂大类可以生产多个不同大类的产品。(可能比较拗口,多想几遍,很好理解):
虽然进一步扩展了工厂模式,但是每次增加新的产品大类的时候,都要给工厂父类(或接口)增加新抽象方法,并让所有的子工厂都去各自实现,就又像文章开头提到的简单工厂模式一样:违反了程序设计中的开闭原则!
总
设计模式,只是前辈们在生产实践中,不断摸索总结出的一系列的指导思想,我们重要的是吸收这种优秀、简练的思想,在实际生产中灵活选择、灵活编码!
菜鸟本菜,不吝赐教,感激不尽!