《Java与模式》之工厂模式学习
Facotry Pattern包括了三种形态
- Simple Factory
- Factory Method
- Abstract Factory
下面分别进行学习
Simple Factory
简单工厂模式往往是普通工厂模式的一个特例。简单工厂模式基本是用一个类来模拟工厂,通过该工厂类的静态方法返回具体的产品类,而这些产品又源自一个抽象的产品(当然,这儿可能会存在多种抽象产品,即有多种不同类型的产品,如蔬菜、瓜果等等),即静态工厂模式。书中提及了几个对象:水果以及具体的水果,园丁;园丁根据得到的参量来决定提取某种水果。如果存在多种抽象产品,必须考察抽象产品是由抽象类来实现还是用接口来表现了,如果具体产品之间拥有共同的商业逻辑,一般都应用抽象类来表现,否则应用接口来表现,在一个类型的等级结构中,将共同的部分尽量向上塑造。相应的,工厂也可以分为多个工厂,各自负责不同种类的产品即抽象类。
考虑一下,如果我们新增了一种产品,那么在我们的静态工厂类中就必须再加入返回该新增的产品类的方法,是需要修改这个工厂类的。这个到底应该如何才能不修改工厂类呢?或许我们的工厂类不应该同具体产品类来发生关联关系。
Factory Method
工厂方法模式是类的创建模式,定义一个创建工厂接口,将实际的创建工作推到子类工厂中。也就是原本的静态类变成了一个抽象类或接口,而将制造的任务交给底下的具体实现类来完成。工厂方法模式似乎同抽象工厂模式很类似,但或许引入产品族后可以做一下比较。
抽象产品A(具体产品A1, 具体产品A2),抽象工厂F可以只有一个具体工厂,实现生成A的抽象方法。即工厂方法模式是将注意集中在可抽象产品概念上(意即多个具体产品可抽象化)。
如果引入产品族的概念,即有多个抽象产品,那么就必须对应不同的抽象产品形成不同的抽象工厂层,这会打破工厂的独立性,乃至形成一个庞大的工厂族。自然工厂方法模式不能很好的解决这种问题。因为有了产品族的引入,自然就引入了抽象工厂模式。
Abstract Factory
这里真正引入了产品族、工厂族的概念。在实际的开发中,我们所面对的产品是分等级的,库存管理系统尤为显现。抽象工厂模式为客户端提供一个接口,使客户端在不必指定产品的具体类型就可以创建多个产品对象。
产品族也就是好有多个抽象产品,其下可能还拥有抽象产品和具体产品。抽象工厂模式,首先抽象出所有产品族的生产方法:
- public interface Creator {
- ProductA factoryA(); //返回产品ProductA
- ProductB factoryB(); //返回产品ProductB
- }
不难发现,这种抽象与抽象产品的种类有关,有多少种抽象产品,就应有多少种抽象工厂方法。具体的生产交给具体工厂去实现。
- /**
- 这是抽象工厂的一个具体实现,它只负责生产ProductA1和ProductB1两种具体产品
- */
- public class ConcreteCreator1 implements Creator {
- public ProductA factoryA() {
- return new ProductA1();
- }
- public ProductB factoryB() {
- return new ProductB1();
- }
- }
可以清楚的发现,该具体工厂仅仅负责所有产品族的各1种产品。ProductA拥有ProductA1, ProductA2两种具体产品, ProductB拥有ProductB1, ProductB2两种具体产品,正因为有了产品族和"1", "2"这两种相对性,我们才能抽象出工厂接口来。可以很容易地写出ConcreteCreator2具体工厂来。
试想一下,如果我们给ProductB再增加2种甚至更多的产品的时候,是否我们需要增加2种或者更多的具体工厂类来实现抽象工厂呢?如果是,那么就会有多余的factoryA()方法被“空实现”。同样我们可以形成工厂族来避免这些问题。
假如我们已经实现了抽象工厂
Client想要某种或多种产品,我们通过抽象工厂提供给它一个接口;
工厂中增加已有抽象的具体产品,可以增加一个具体工厂而不需要去修改其它的设计;
工厂中要增加新的抽象层面的产品,新增一个抽象产品类,增加所需要的具体产品,那么抽象工厂层是否需要修改,这似乎就违背了不修改现有代码的初衷了。是,这很麻烦,因为你需要重新抽象,甚至要修改以前的代码。可以考虑用其它方法解决。
小结
简单工厂模式和工厂方法模式可以看作是抽象工厂模式特例,当我们把简单工厂模式中的实际工厂抽象出一个抽象工厂时,它就变成了一个工厂方法模式;当我们把工厂方法模式的产品等级变得更多一些,形成产品族的时候,它又能成为一个抽象工厂模式。