工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类。
工厂方法实现时,由客户端决定实例化哪个工厂来实现具体的产品类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。每个具体的产品类都对应着一个具体的工厂类。
工厂方法模式中有如下四种角色:
Product(产品):Product角色属于框架这一方,是一个抽象类。定义了在工厂方法模式中生成的那些实例所持有的接口(API),但具体的处理则由子类ConcreteProduct角色决定。
Factory(工厂):Factory角色属于框架这一方,它是负责生成Product角色的抽象类,但具体的处理则由子类ConcreteFactory角色决定。不用new关键字来生成实例,而是调用生成实例的专用方法来生成实例,防止父类与其他具体类耦合。
ConcreteProduct(具体的产品):ConcreteProduct属于具体加工的这一方,它决定了具体的产品。
ConcreteFactory(具体的工厂):ConcreteFactory属于具体加工的这一方,它负责生成具体的产品。
下面这个例子中,为了更清楚表现层次关系,把抽象的产品类Product和抽象的工厂类Factory放到framework包中,而具体的产品类ProductA和ProductB及具体的工厂类FactoryA和FactoryB放到concrete包中。
抽象类:
package framework;
public abstract class Product {
public abstract void Show();
}
package framework;
public abstract class Factory {
public abstract Product Manufacture();
}
具体实现的类:
package concrete;
import framework.Product;
public class ProductA extends Product {
@Override
public void Show() {
System.out.println("生产出了产品A");
}
}
package concrete;
import framework.Product;
public class ProductB extends Product {
@Override
public void Show() {
System.out.println("生产出了产品B");
}
}
package concrete;
import framework.Factory;
import framework.Product;
public class FactoryA extends Factory {
@Override
public Product Manufacture() {
return new ProductA();
}
}
package concrete;
import framework.Factory;
import framework.Product;
public class FactoryB extends Factory {
@Override
public Product Manufacture() {
return new ProductB();
}
}
客户端调用过程:
import concrete.FactoryA;
import concrete.FactoryB;
public class Main {
public static void main(String[] args) {
//客户要产品A
FactoryA mFactoryA = new FactoryA();
mFactoryA.Manufacture().Show();
//客户要产品B
FactoryB mFactoryB = new FactoryB();
mFactoryB.Manufacture().Show();
}
}
工厂方法模式可以说是简单工厂模式的进一步抽象和拓展,克服了简单工厂违背开放-封闭原则的缺点。但工厂模式的缺点是每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。