前言

工厂方法模式是一种结构简单的模式,并且在我们的应用中很广泛,如Android中Activity的各个生命周期的回调,以onCreate方法为例,它就可以看做是一个工厂方法,我们在其中构造我们的View并返回给framework处理。

定义

定义一个用于创建对象的接口,让子类决定实例化哪个类。

使用场景

在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂方法模式,用new就能完成创建的对象无需使用工厂方法模式。

类图

角色介绍:

  • Factory - 抽象工厂,是工厂方法的核心
  • ConcreteFactory - 具体工厂,实现了业务逻辑
  • Product - 抽象产品,是工厂方法模式所创建的产品的父类
  • ConcreteProduct - 为实现抽象产品的某个具体产品

简单实现

下面生产汽车为例,要生产三款汽车,于是使用一条生产线来生产,我们先定义产品,产品是汽车。

抽象汽车,即抽象产品

1
2
3
public abstract class Car {
public abstract void drive();
}

接下来是具体的车型

奥迪汽车,即具体的产品类

1
2
3
4
5
6
public class AudiCar extends Car {
@Override
public void drive() {
System.out.println("奥迪汽车开始启动啦!");
}
}

奔驰汽车,即具体的产品类

1
2
3
4
5
6
7
public class BenzCar extends Car {

@Override
public void drive() {
System.out.println("奔驰车开始启动啦!");
}
}

宝马汽车,即具体的产品类

1
2
3
4
5
6
public class BWMCar extends Car {
@Override
public void drive() {
System.out.println("宝马汽车开始启动啦!");
}
}

有了产品就要有工厂来生产,定义一个汽车抽象工厂。

抽象汽车工厂,即抽象工厂角色

1
2
3
public abstract class CarFactory {
public abstract Car createCar();
}

接下来是具体的车型工厂。

生产奥迪车的工厂,即具体工厂类

1
2
3
4
5
6
7
8
public class AudiCarFactory extends CarFactory {

@Override
public Car createCar() {
return new AudiCar();
}

}

生产奔驰车的工厂,即具体工厂类

1
2
3
4
5
6
public class BenzCarFactory extends CarFactory {
@Override
public Car createCar() {
return new BenzCar();
}
}

生产宝马车的工厂,即具体工厂类

1
2
3
4
5
6
public class BWMCarFactory extends CarFactory {
@Override
public Car createCar() {
return new BWMCar();
}
}

最后我们将各个汽车的生产组装成一条生产线。

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Client {

public static void main(String[] args){
//制造各个工厂
CarFactory audiFactory = new AudiCarFactory();
CarFactory benzFactory = new BenzCarFactory();
CarFactory bwmFactory = new BWMCarFactory();
//生产各种车
Car audiCar = audiFactory.createCar();
Car benzCar = benzFactory.createCar();
Car bwmCar = bwmFactory.createCar();
//车启动
audiCar.drive();
benzCar.drive();
bwmCar.drive();
}
}

输出结果:
奥迪汽车开始启动啦!
奔驰车开始启动啦!
宝马汽车开始启动啦!

可以看到我们需要哪种车型就可以定义哪种车型的具体工厂,像这样拥有多个工厂的的方式我们称之为多工厂模式,每个工厂各司其职。

但上面的方式不好的是会产生大量工厂,使代码臃肿,在实际开发中,我们可以使用反射的方式更加简洁的来生产具体的产品对象,此时需要在工厂方法的参数列表中传入一个Class类来决定是哪一个产品类。

使用反射的方式来生产具体的产品对象,抽象工厂角色

1
2
3
4
5
6
7
8
public abstract class CarFactory2 {

/**
* 抽象工厂方法,具体生产什么产品由子类决定
*/
public abstract <T extends Car> T createCar(Class<T> car);

}

对于 具体的工厂,则通过反射获取类的实例即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ConcreteCarFactory extends CarFactory2 {

@Override
public <T extends Car> T createCar(Class<T> car) {
Car c = null;
try {
c = (T) Class.forName(car.getName()).newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T) c;
}

}

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Client {

public static void main(String[] args){
//创建工厂
CarFactory2 carFactory = new ConcreteCarFactory2();
//生产车
AudiCar audiCar = carFactory.createCar(AudiCar.class);
BenzCar benzCar = carFactory.createCar(BenzCar.class);
BWMCar bwmCar = carFactory.createCar(BWMCar.class);
//车启动
audiCar.drive();
benzCar.drive();
bwmCar.drive();
}
}

输出和和上面一样,使用反射的方式,需要哪一个产品的对象,就传入哪一个产品的类的型即可,这种方式比较简洁,动态。

上面我们有三个工厂,如果我们只需要生产一种车型,即我们只有一个工厂时,我们就可以把抽象工厂简化掉,将对应的工厂方法改为静态方法,像下面,我们只生产一辆五菱车。

一个工厂,只生产一种产品

1
2
3
4
5
6
7
public class Factory {

public static Car createWuLingCar(){
return new WuLingCar();
}

}

像这样的方式又称为简单工厂方式或静态工厂方式,它是工厂方式模式的一个弱化版本。

总结

工厂模式依赖于抽象的架构,将实例化的具体任务交给子类去完成,有非常好的扩展性。

本文源码相关位置