工厂方法设计模式是开发中比较常用的一种。主要是辅助相似类型的多种对象的创建。与之相匹配的,有更加灵活的抽象工厂方法模式,有使用更加简单的简单工厂方法模式(也叫静态工厂方法模式)。
定义
工厂方法模式
定义一个统一的产品类接口,利用子类来决定具体要创建的对象。
抽象工厂方法模式
定义一个统一的产品类接口和工厂类接口,利用不同的工厂实现类来创建多组不同的对象
场景
- 复杂对象的创建
- 相似特征的一些对象的创建
特点
- 通过具体的工厂来完成对应产品的组装
- 统一的产品类接口,具体的子类对象
- 构建细节被隐藏
- 客户端面向接口,高扩展性
各种模式的描述
普通工厂方法
具备两个要素
- 抽象产品类接口
- 工厂类抽象工厂方法
通过实现工厂类的抽象方法来生成不同的产品类实例。实现参照以下代码
/**
* 工厂
*/
public interface IFactory {
IProduction create();
}
/**
* 抽象产品
*/
public interface IProduction {
double price();
}
通过重写工厂方法来创建产品实例
/**
* 具体产品
*/
public class Production implements IProduction {
@Override public double price() {
return 99.99;
}
}
/**
* 具体的工厂实现类,创建具体的对象
*/
public class Factory implements IFactory {
@Override public IProduction create() {
return new Production();
}
}
这是一种标准的工厂方法模式的描述,通过实现抽象工厂方法来创建具体的实例对象。
静态工厂(简单工厂)方法
具备两个要素
- 抽象产品类接口
- 静态工厂方法
产品类接口同普通工厂方法一样。区别在于省略了抽象工厂方法,通过调用静态工厂方法的形式来完成实例的创建。
public class SimpleFactory {
public static IProduction create(String production) {
if ("Apple".equals(production)) {
return new Apple();
} else if ("Pear".equals(production)) {
return new Pear();
}
throw new IllegalArgumentException("no production found.");
}
public static class Apple implements IProduction {
@Override public double price() {
return 5.5;
}
}
public static class Pear implements IProduction {
@Override public double price() {
return 4.5;
}
}
}
上面SimpleFactory
类中通过静态工厂方法create
和产品类接口IProduction
,根据不同输入来生成不同的产品对象。这种方式可以在创建具有相同特征的对象时简化创建流程。
抽象工厂方法
在工厂方法的基础上,对可工厂和产品进行了跟高的抽象,定义为可以创建多组对象。
该模式至少拥有:
- 抽象产品接口
- 抽象工厂接口
- 抽象工厂方法
比如,在装配汽车的时候会涉及到很多型号和零件。在这里,就产生了两种标准,一种是型号,一种是零件。
型号包括X3、X5等,零件包括轮胎、发动机等。在这种场景下,通过简单工厂方法来处理,就会比较麻烦。他需要一种更新加灵活的装配规则。
利用抽象工厂模式,可以解决上述问题。
在抽象工厂中定义一组抽象工厂方法。
/**
* 汽车装配工厂
*/
public interface CarFactory {
String create()
Tire createTire();
Engine createEngine();
interface Tire {
String create();
}
interface Engine {
String create();
}
}
然后通过组装不同的工厂来完成不同车辆的生产
/**
* X3装配工厂
*/
public class X3Factory implements CarFactory {
@Override public String create() {
return "X3汽车";
}
@Override public Tire createTire() {
return new X3Tire();
}
@Override public Engine createEngine() {
return new X3Engine();
}
public static class X3Tire implements CarFactory.Tire {
@Override public String create() {
return "X3轮胎";
}
}
public static class X3Engine implements CarFactory.Engine {
@Override public String create() {
return "X3发动机";
}
}
}
类似的,新增X5工厂
/**
* X5装配工厂
*/
public class X5Factory implements CarFactory {
@Override public String create() {
return "X5汽车";
}
@Override public Tire createTire() {
return new X5Tire();
}
@Override public Engine createEngine() {
return new X5Engine();
}
public static class X5Tire implements CarFactory.Tire {
@Override public String create() {
return "X5轮胎";
}
}
public static class X5Engine implements CarFactory.Engine {
@Override public String create() {
return "X5发动机";
}
}
}
在此基础上,在装配汽车时,只需要通过具体的汽车工厂类来实现即可,例如生产X5汽车:
public void main() {
X5Factory x5Factory = new X5Factory();
x5Factory.createEngine();
x5Factory.createTire();
x5Factory.create();
}
总结
工厂方法的实现比较简单,主要是解决一类对象或者多组相似对象的创建问题。优势是创建流程更加清晰易懂,客户端针对接口编程,不用关心实现类的细节,耦合度低、扩展性强、灵活度高。缺点也很明显,每增加一个产品,就需要创建对应的工厂类或者实现工厂方法,会额外创建实现类。
在实际工作中,静态工厂方法因之简单的实现机制、调用规则,在实际项目开发中使用率较高。