简单工厂模式虽然简单,但存在一个很严重的问题。当系统中需要引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,这必定要修改工厂类的源代码,将违背“开闭原则”,如何实现增加新产品而不影响已有代码?工厂方法模式应运而生。
模式定义在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级结构。工厂方法模式定义如下:
工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。工厂方法模式是一种类创建型模式。
模式结构图工厂方法模式提供一个抽象工厂接口来声明抽象工厂方法,而由其子类来具体实现工厂方法,创建具体的产品对象。工厂方法模式结构如图所示:
在工厂方法模式结构图中包含如下几个角色:
Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。
ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
Factory(抽象工厂):在抽象工厂类中,声明了工厂方法(Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户端调用,返回一个具体产品类的实例。
模式伪代码与简单工厂模式相比,工厂方法模式最重要的区别是引入了抽象工厂角色,抽象工厂可以是接口,也可以是抽象类或者具体类,其典型代码如下所示:
public interface Factory { Product factoryMethod(); }在抽象工厂中声明了工厂方法但并未实现工厂方法,具体产品对象的创建由其子类负责,客户端针对抽象工厂编程,可在运行时再指定具体工厂类,具体工厂类实现了工厂方法,不同的具体工厂可以创建不同的具体产品,其典型代码如下所示:
public class ConcreteFactory implements Factory { @Override public Product factoryMethod() { return new ConcreteProduct(); } }在客户端代码中,只需关心工厂类即可,不同的具体工厂可以创建不同的产品,典型的客户端类代码片段如下所示:
public class Client { public static void main(String[] args) { // 确定是哪个工厂可得到产品 Factory factory = new ConcreteFactory(); // 获取产品 Product product = factory.factoryMethod(); } } 模式简化有时候,为了进一步简化客户端的使用,还可以对客户端隐藏工厂方法,此时,在工厂类中将直接调用产品类的业务方法,客户端无须调用工厂方法创建产品,直接通过工厂即可使用所创建的对象中的业务方法。
// 改为抽象类 public class AbstractFactory { // 在工厂类中直接调用产品类的业务方法 public void productMethod() { Product product = this.createProduct(); product.method(); } public abstract Product createProduct(); }通过将业务方法的调用移入工厂类,可以直接使用工厂对象来调用产品对象的业务方法,客户端无须直接调用工厂方法,在客户端并不关心Product细节的情况下使用这种设计方案会更加方便。
模式小结工厂方法模式能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。
抽象工厂模式工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时,我们可以考虑将一些相关的产品组成一个产品族,由同一个工厂来统一生产,这就是我们本文将要学习的抽象工厂模式的基本思想。
这里我斗胆举个例子来说明一下吧,如果不恰当欢迎指出。
众所周知,国内知名的电器厂有海尔、海信(姑且就认为是2个),电器厂会生产电视机、电冰箱、空调(姑且就认为是3种产品)。