定义:
抽象工厂模式是工厂方法模式的升级版。抽象工厂模式的定义是为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类,抽象工厂模式对应的是更复杂的情况。在工厂方法模式中,如有新的需求改动,只能修改工厂类,新增或修改工厂类,到但是工厂方法模式只是针对一个系列的产品,如果是多个系列的产品呢?抽象工厂模式应运而生。
示例:
还是关于造车的例子,在工厂方法的示例的造的是汽车,是厂子的常规业务。之前的工厂主要是汽车组装,是代加工。但是由于今年疫情的原因,进出口贸易受到限制。很多汽车的配件贸易受到限制。老板决定自己研发汽车的配件,主要先从轮胎和油漆开始。但是之前的工厂是专门来组装汽车的,如果要研发生产轮胎和油漆,只能改工厂完全改造。但是汽车毕竟是主营业务,而且效益也是最高的。疫情毕竟只是暂时的,主要业务恢复只是时间问题。所有老板决定新建一个工厂来生产汽车配件,受到汽车的等级不同,生产的配件也会有等级上的区别。分两个车间,一个车间生产专门生产等级A的产品,另一个车间生成等级B的产品。
/**
* 接口
*/
public interface PartsFactory {
}
/**
* 生产B等级的汽车配件抽象工厂
*/
public abstract class AbstractAutoPartAFactory implements PartsFactory {
//生产B等级轮胎
public abstract AbstractAutoPartA creatTyreA();
//生产B等级油漆
public abstract AbstractAutoPartA creatPaintA();
}
/**
* 生产A等级的汽车配件实际工厂
*/
public class AutoPartAFactory extends AbstractAutoPartAFactory{
@Override
public AbstractAutoPartA creatTyreA() {
return new TyreA();
}
@Override
public AbstractAutoPartA creatPaintA() {
return new PaintA();
}
}
注:B等级代码类似,这里就不赘述了
工厂建好了,来看下即将要生产的产品,目前要生产的产品主要是油漆和轮胎两种汽车配件,两种配件又分为A、B两个等级。
/**
* 汽车配件
*/
public interface AutoPart {
}
/**
* A等级汽车配件
*/
public abstract class AbstractAutoPartA implements AutoPart{
//配件的基本功能
public abstract void getFunction();
//配件的等级
public abstract void getGrade();
}
/**
* A等级油漆
*/
public class PaintA extends AbstractAutoPartA{
@Override
public void getFunction() {
System.out.println("油漆");
}
@Override
public void getGrade() {
System.out.println("A等级");
}
}
**
* A等级轮胎
*/
public class TyreA extends AbstractAutoPartA{
@Override
public void getFunction() {
System.out.println("轮胎");
}
@Override
public void getGrade() {
System.out.println("A等级");
}
}
产品和工厂都准备就续剩下的就是开足马力准备生产了
public class TestAbstarctFactory {
public static void main(String[] args) {
//开动生产线
AbstractAutoPartAFactory factoryA = new AutoPartAFactory();
AbstractAutoPartBFactory factoryB = new AutoPartBFactory();
//开足马力开始生产
System.out.println("奔驰的配件订单.......");
AbstractAutoPartA BMWPaint = factoryA.creatPaintA();
BMWPaint.getFunction();
BMWPaint.getGrade();
AbstractAutoPartA BMWTyre = factoryA.creatTyreA();
BMWTyre.getFunction();
BMWTyre.getGrade();
System.out.println("奥拓的配件订单.......");
AbstractAutoPartB AUTOPaint = factoryB.creatPaintB();
AUTOPaint.getFunction();
AUTOPaint.getGrade();
AbstractAutoPartB AUTOType = factoryB.creatTyreB();
AUTOType.getFunction();
AUTOType.getGrade();
}
}
执行结果:
奔驰的配件订单.......
油漆
A等级
轮胎
A等级
奥拓的配件订单.......
油漆
B等级
轮胎
B等级
解读:
抽象工厂模式具有良好的封装性,上层模块并不考虑产品产生的细节,只是需要获得产品,而且是多个产品。虽然抽象工厂的确解决了工厂方法模式不支持多系列的产品的问题。但是也存在同样的问题。如上面的例子中,如果想增加一个系列。那么需要修改的抽象工厂AbstractAutoPartAFactory 和实现类以及新增一个产品类。违背了开闭原则。这也是抽象工厂模式最大的弊端。但是,如果在同一个系列中要扩展一个新的等级的产品呢?只需要新建一个工厂就可以实现,从这一角度又满足了开闭原则。所以抽象工厂是横向扩展容易,纵向扩展困难。所以在设计过程中要充分考虑纵向扩展的可能性,不要冗余也不要过于保守。
应用场景:
抽象工厂模式真正解决是多产品多系场景。每个系列之间存在约束,每个系列产品之间也存在等级上的约束。当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。