前言
工厂方法模式是一种结构简单的模式,并且在我们的应用中很广泛,如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(); } }
|
像这样的方式又称为简单工厂方式或静态工厂方式,它是工厂方式模式的一个弱化版本。
总结
工厂模式依赖于抽象的架构,将实例化的具体任务交给子类去完成,有非常好的扩展性。
本文源码相关位置
最終更新:
谢谢大家的阅读!