个人理解,工厂模式的好处有两点
1.初始化实现类的参数,简化实现类的创建,特别是参数多的时候很实用
2.可以对相同类型的类创建进行归类,且容易维护,比如如果某个实现类的创建过程,增加了新的参数需要初始化或者某个初始化参数需要改动,那么只需要修改工厂类中的实例化方法,不需要去修改所有创建这个类的代码。
1.简单工厂模式
描述:通过传递参数创建参数对应的实体类,即可根据不同情况创建不同的实现类
实体类 车辆抽象类,单车类和汽车类继承车辆类
/**
* 车辆
* */
public abstract class Vehicle {
/**
* 来源
* */
protected String origin;
/**
* 轮子数
* */
protected int wheelSum;
/**
* 描述
* */
public abstract void desc();
}
/**
* 单车
* */
public class Bike extends Vehicle {
public Bike(int wheelSum){
this.wheelSum = wheelSum;
}
public Bike(int wheelSum,String origin){
this.wheelSum = wheelSum;
this.origin = origin;
}
@Override
public void desc() {
Optional.ofNullable(origin).ifPresent(bikeOrigin ->
System.out.println("我是单车 我是"+bikeOrigin+"制造")
);
System.out.println("我是单车 我有"+wheelSum+"个轮子");
}
}
/**
* 汽车
* */
public class Car extends Vehicle {
public Car(int wheelSum){
this.wheelSum = wheelSum;
}
public Car(int wheelSum,String origin){
this.wheelSum = wheelSum;
this.origin = origin;
}
@Override
public void desc() {
Optional.ofNullable(origin).ifPresent(carOrigin ->
System.out.println("我是汽车 我是"+carOrigin+"制造")
);
System.out.println("我是汽车 我有"+wheelSum+"个轮子");
}
}
简单工厂类 设定枚举类型,每次创建根据传递的枚举类型创建对应的实例
public class SimpleFactory{
/**
* 车类型枚举
* */
public enum VehicleType{
BIKE(1,"单车"),
CAR(2,"汽车");
private Integer type;
private String desc;
VehicleType(Integer type,String desc){
this.type = type;
this.desc = desc;
}
}
/**
* 创建实例
* @param vehicleType 车类型
* */
public static Vehicle newInstance(VehicleType vehicleType){
switch (vehicleType){
case BIKE:
return new Bike(2);
case CAR:
return new Car(4);
default:return null;
}
}
}
main方法
public class Main {
public static void main(String[] args) {
Vehicle fruit = SimpleFactory.newInstance(SimpleFruitFactory.VehicleType.BIKE);
fruit.desc();
}
}
运行结果
2.方法工厂模式
描述:每个创建实例新建一个创建方法
方法工厂 类
public class MultiMethodFactory {
/**
* 创建单车
* */
public static Bike newBikeInstance(){
return new Bike(2);
}
/**
* 创建汽车
* */
public static Car newCarInstance(){
return new Car(4);
}
}
main方法
public class Main {
public static void main(String[] args) {
Vehicle vehicle = MultiMethodFactory.newBikeInstance();
vehicle.desc();
}
}
相比第一种的优势是,新增创建实例无需改动原有的创建实例逻辑,不会影响到之前的功能,而且参数的接收也更加自由,不同的创建实例方法,可以设定不同的接收参数。
concurrent包下的Executors类创建线程池便是使用这种方式。
3.抽象工厂模式
描述:不仅抽象需要创建的类,工厂也进行抽象分类
抽象工厂
/**
* 车辆工厂
* */
public abstract class VehicleFactory {
/**
* 创建单车
* */
public abstract Bike newBikeInstance();
/**
* 创建汽车
* */
public abstract Car newCarInstance();
}
工厂实现类
/**
* 中国车辆工厂
* */
public class ChinaVehicleFactory extends VehicleFactory {
// 中国
private static final String CHINA = "china";
@Override
public Bike newBikeInstance() {
return new Bike(2,CHINA);
}
@Override
public Car newCarInstance() {
return new Car(4,CHINA);
}
}
/**
* 法国车辆工厂
* */
public class FranceVehicleFactory extends VehicleFactory {
// 法国
private static final String FRANCE = "France";
@Override
public Bike newBikeInstance() {
return new Bike(2,FRANCE);
}
@Override
public Car newCarInstance() {
return new Car(4,FRANCE);
}
}
main方法
public class Main {
public static void main(String[] args) {
Vehicle vehicle = new ChinaVehicleFactory().newBikeInstance();
vehicle.desc();
}
}
创建的实例根据工厂的不同,车辆的来源属性也不同。
抽象工厂可以在工厂层加多一层分类,只要新增一个类,扩展比较容易,但是也导致对应的类变得更多,更重。