介绍
工厂方法模式是一种结构简单的模式,并且在我们的应用中很广泛,如Android中Activity的各个生命周期的回调,以onCreate方法为例,它就可以看做是一个工厂方法,我们在其中构造我们的View并返回给framework处理。
定义
定义一个用于创建对象的接口,让子类决定实例化哪个类。
工厂方法模式的
在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂方法模式,用new就能完成创建的对象无需使用工厂方法模式。
类图
角色介绍:
- Factory - 抽象工厂,是工厂方法的核心
- ConcreteFactory - 具体工厂,实现了业务逻辑
- Product - 抽象产品,是工厂方法模式所创建的产品的父类
- ConcreteProduct - 为实现抽象产品的某个具体产品
简单实现
下面生产汽车为例,要生产三款汽车,于是使用一条生产线来生产,我们先定义产品,产品是汽车。
抽象汽车,即抽象产品
public abstract class Car {
public abstract void drive();
}
接下来是具体的车型
奥迪汽车,即具体的产品类
public class AudiCar extends Car {
@Override
public void drive() {
System.out.println("奥迪汽车开始启动啦!");
}
}
奔驰汽车,即具体的产品类
public class BenzCar extends Car {
@Override
public void drive() {
System.out.println("奔驰车开始启动啦!");
}
}
宝马汽车,即具体的产品类
public class BWMCar extends Car {
@Override
public void drive() {
System.out.println("宝马汽车开始启动啦!");
}
}
有了产品就要有工厂来生产,定义一个汽车抽象工厂。
抽象汽车工厂,即抽象工厂角色
public abstract class CarFactory {
public abstract Car createCar();
}
接下来是具体的车型工厂。
生产奥迪车的工厂,即具体工厂类
public class AudiCarFactory extends CarFactory {
@Override
public Car createCar() {
return new AudiCar();
}
}
生产奔驰车的工厂,即具体工厂类
public class BenzCarFactory extends CarFactory {
@Override
public Car createCar() {
return new BenzCar();
}
}
生产宝马车的工厂,即具体工厂类
public class BWMCarFactory extends CarFactory {
@Override
public Car createCar() {
return new BWMCar();
}
}
最后我们将各个汽车的生产组装成一条生产线。
客户端
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类来决定是哪一个产品类。
使用反射的方式来生产具体的产品对象,抽象工厂角色
public abstract class CarFactory2 {
/**
* 抽象工厂方法,具体生产什么产品由子类决定
*/
public abstract <T extends Car> T createCar(Class<T> car);
}
对于 具体的工厂,则通过反射获取类的实例即可
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;
}
}
客户端
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();
}
}
输出和和上面一样
以上的方式,需要哪一个产品的对象,就传入哪一个产品的类的型即可,这种方式比较简洁,动态。
上面我们有三个工厂,如果我们只需要生产一种车型,即我们只有一个工厂时,我们就可以把抽象工厂简化掉,将对应的工厂方法改为静态方法,像下面,我们只生产一辆五菱车。
一个工厂,只生产一种产品
public class Factory {
public static Car createWuLingCar(){
return new WuLingCar();
}
}
像这样的方式又称为简单工厂方式或静态工厂方式,它是工厂方式模式的一个弱化版本。
总结
工厂模式依赖于抽象的架构,将实例化的具体任务交给子类去完成,有非常好的扩展性。