9.3.3 工厂方法和抽象工厂
9.3.3 工厂方法和抽象工厂
在简单工厂模式里,系统使用工厂类生产所有产品实例,且该工厂类决定生产哪个类的实例,即该工厂类负责所有的逻辑判断、实例创建等工作。
如果不想在工厂类中进行逻辑判断,程序可以为不同产品类提供不同的工厂,不同的工厂类生产不同的产品。例如为上面的Printer
、 Better Printer
分别提供PrinterFactory
和BetterPrinterFactory
工厂类,这就无须在工厂类进行复杂的逻辑判断。
程序示例
1 | E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\FactoryMethod |
本示例应用将OutputFactory
改为一个接口,并为该接口提供两个实现类:PrinterFactory.java
和BetterPrinterFactory.java
。下面是OutputFactory
接口的代码。
1 | public interface OutputFactory |
上面的OutputFactory
只是一个接口,该接口提供了一个getOutput0
方法,该方法可直接返回一个输出设备。
下面为OutputFactory
接口提供一个PrinterFactory
实现类,该实现类专门负责生成Printer
实例。
1 | public class PrinterFactory implements OutputFactory |
上面的PrinterFactory
实现了OutputFactory
接口,并实现了该接口里的getOutput()
方法,该方法直接返回一个简单的Printer
对象。
下面再为OutputFactory
接口提供一个BetterPrinterFactory
实现类,该实现类专门负责生成BetterPrinter
实例。
1 | public class BetterPrinterFactory implements OutputFactory |
本示例应用中各类之间的类图如图9.2所示。
当使用工厂方法设计模式时,对象调用者需要与具体的工厂类耦合:当需要不同对象时,程序需要调用相应工厂对象的方法来得到所需的对象。如下是Computer
类中创建Output
对象并调用该对象方法的代码。
1 | public class Computer |
正如程序中main方法中第一行代码所示,当客户端代码需要调用Ouput
对象的方法时,为了得到不同的Output
实例,程序必须显式创建不同的OutputFactory
实例,程序中创建的是PrinterFactory
实例。
从上面的代码可以看出,对于采用工厂方法的设计架构,客户端代码成功与被调用对象的实现类分离,但带来了另一种耦合:客户端代码与不同的工厂类耦合。这依然是一个问题!
抽象工厂模式
为了解决客户端代码与不同工厂类耦合的问题,接着考虑再增加一个工厂类,该工厂类不是生产Output
对象,而是生产OutputFactory
实例,简而言之,这个工厂类不制造具体的被调用对象,而是制造不同工厂对象。这个特殊的工厂类被称呼抽象工厂类
,这种设计方式也被称为抽象工厂模式
。如图9.3所示是抽象工厂模式示例的UML
类图。
从图9.3中可以看出,在这种模式下系统新增了一个OutputFactoryFactory
工厂类,该工厂类提供了一个getOutputFactory(String type)
方法,该方法用于返回一个OutputFactory
工厂实例。
程序示例
1 | E:\workspace_QingLiangJiJavaEEQiYeYingYongShiZhang5\AbstractFactory |
下面是该抽象工厂类的代码。
1 | public class OutputFactoryFactory |
从上面的粗体字代码可以看出,抽象工厂根据type
参数进行判断,决定需要生成哪种工厂实例。通过这种设计模式,就可让客户端程序只需与抽象工厂类耦合。下面是客户端调用被调用者对象方法的主方法。
1 | public class Computer |
上面程序中的粗体字代码用于产生一个OutputFactory
工厂,但具体产生哪个工厂则由OutputFactoryFactory
抽象工厂决定,不同的工厂对象将产生不同的Output
对象。
通过采用抽象工厂的设计模式,系统可以让客户端代码与被调用对象的实现类、具体的工厂类分离。
读者掌握了这种抽象工厂模式后,应该对Spring IoC
容器感到迷惑:它到底是简单工厂,还是抽象工厂?本书倾向于认为Spring loc
容器是抽象工厂,因为Sping loc
容器可以包括万象,它不仅可以管理普通Bean
实例,也可管理工厂实例。
不要过分纠缠于简单工厂模式、抽象工厂模式这些概念,可以把它们统称为工厂模式。
- 如果工厂直接生产被调用对象,那就是简单工厂模式;
- 如果工厂生产了工厂对象,那就会升级成抽象工厂模式。