携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
简介
工厂模式也是一种很常见的设计模式。简单来说就是把要new的类放到一个统一的类中,这个类就叫做工厂类,它就是一个产生类的工厂。这样由工厂类统一创建同一个类型的类,方便管理和拓展。
但是工厂方法又有好几种,什么简单工厂方法、静态工厂方法、工厂方法、抽象工厂方法。今天咱们就来简单聊一聊。
案例
简单工厂方法
public abstract class Car {
abstract void drive();
}
public class Benz extends Car {
@Override
void drive() {
System.out.println("奔驰开");
}
}
public class Bmw extends Car {
@Override
void drive() {
System.out.println("宝马开");
}
}
public class CarFactory {
public static Car getCarByType(String type) {
if (Objects.equals("1", type)) {
return new Bmw();
}else if(Objects.equals("2", type)) {
return new Benz();
}else {
return null;
}
}
}
public class DriverCar {
public static void main(String[] args) {
Car car = CarFactory.getCarByType("1");
car.drive();
Car car1 = CarFactory.getCarByType("2");
car1.drive();
}
}
如上面的代码,一个抽象的Car,一个宝马一个奔驰分别继承抽象类Car,一个生产车的工厂类CarFactory,然后一个应用的开车类。这样就实现了简单工厂模式。开车的类中通过传入需要获取的车的类型来调用CarFactory,工厂类根据入参类型返回不同类型的车的实现。
这里CarFactory的getCarByType是一个静态方法,所以简单工厂模式也就叫做静态工厂模式。通过简单工厂模式,我们将创建Car的过程统一放到工厂类里面,统一管理。但是如果后续拓展需要增加车的类型,不仅需要增加一个对Car的继承类,还要在工厂类里面修改,增加新增的这个车型的实例返回逻辑。所以这种简单工厂模式虽然抽取了创建车的过程在一个类里,但是并不是符合开闭原则。下面我们将看看工厂方法模式是怎么解决这个问题的。
工厂方法模式
public abstract class Car {
abstract void drive();
}
public class Benz extends Car{
@Override
void drive() {
System.out.println("奔驰开");
}
}
public class Bmw extends Car{
@Override
void drive() {
System.out.println("宝马开");
}
}
public abstract class AbsCarFactory {
abstract Car produce();
}
public class BenzFactory extends AbsCarFactory {
@Override
Car produce() {
return new Benz();
}
}
public class BmwFactory extends AbsCarFactory{
@Override
Car produce() {
return new Bmw();
}
}
public class DriverCar {
public static void main(String[] args) {
new BenzFactory().produce().drive();
new BmwFactory().produce().drive();
}
}
很明显我们看到工厂方法模式的代码量大大地增加了,相比简单工厂方法模式我们类的数量成倍地增加了。我们看到工厂方法模式在创建Car的工厂类这一层也做了抽象处理,每一个Car均有了自己独立的XXCarFactory,这样的好处是我们不用去通过类型来调用工厂方法了,而是直接在应用层根据需要通过实例化不同Car的工厂方法即可得到对应的工厂,然后再通过该工厂去创建一个我们最终需要的Car。而后续如果需要增加一个新的类型,那么我们可以通过新增一个Car的实现,然后新增一个这个Car的工厂类即可,也满足了开闭原则。
总结
可以看到,虽然工厂方法的的灵活性变得更好了,满足开闭原则,可以随意增加新的类型的车进来,但是一旦新增一个类型的车就要增加2个类,这样在维护上也带来了一定的麻烦,在类的总数量上翻倍,那维护的困难层度上应该也会是翻倍的。因此我们在使用工厂方法是,如果不是特殊要求和场景,不建议都使用工厂方法,一般情况下简单工厂即可满足要求,我们不能为了满足原则而满足,也要考虑代码的简洁和可维护性。