抽象工厂就是一个把工厂抽象,工厂模式生产的是产品,抽象工厂生产的是工厂。这种类型的设计模式属于创建型模式。
就相当于一个工厂生产一件产品,现在有多个产品了。比如生产汽车,首先一个工厂用于生产汽车原胚,另一个工厂用于生产汽车颜料,但这两个工厂都属于同一个集团,由集团统一进行组合成不同颜色的车进行售卖,集团就是这个抽象工厂。
那么抽象工厂用来干嘛呢?
抽象工厂提供了一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体类,主要也是解决接口选择的问题。
怎么实现抽象工厂呢?
在工厂模式的基础上,再抽象出一个更大的工厂用于生产这些工厂
首先我们需要先有至少2个工厂模式(CarFactory和ColorFactory)去生产产品,这两个工厂类都继承于集团的这个抽象工厂(AbstractFactory)
public abstract class AbstractFactory {
public abstract Car getCar(String carName);
public abstract Color getColor(String color);
}
这里可以看到,集团的这个抽象工厂(AbstractFactory)里聚合了2个工厂模式(CarFactory和ColorFactory),用于生产产品
public class CarFactory extends AbstractFactory {
@Override
public Car getCar(String carName) {
if(carName == null){
return null;
}
if("CarOne".equals(carName)){
return new CarOne();
}
if("CarTwo".equals(carName)){
return new CarTwo();
}
return null;
}
@Override
public Color getColor(String color) {
return null;
}
}
public class ColorFactory extends AbstractFactory {
@Override
public Car getCar(String carName) {
return null;
}
@Override
public Color getColor(String color) {
if(color == null){
return null;
}
if("red".equals(color)){
return new RedColor();
}
if("blue".equals(color)){
return new BlueColor();
}
return null;
}
}
现在我们有了2个工厂模式(工厂模式的具体实现请看工厂模式(Factory)),那么怎么去生产工厂,再让工厂去生产产品呢?就需要一个工厂的生产类AbstractFactoryProducer
public class AbstractFactoryProducer {
public static AbstractFactory getFactory(String factoryName){
if("Car".equals(factoryName)){
return new CarFactory();
}
if("Color".equals(factoryName)){
return new ColorFactory();
}
return null;
}
}
这样我们就能随意的获取指定的工厂去生产对应的产品
public class AbstractFactoryDemoTest {
public static void main(String[] args) {
// 获取车辆生产工厂
AbstractFactory carFactory = AbstractFactoryProducer.getFactory("Car");
// 获取车辆
assert carFactory != null;
Car carOne = carFactory.getCar("CarOne");
carOne.get();
Car carTwo = carFactory.getCar("CarTwo");
carTwo.get();
// 获取颜色生产工厂
AbstractFactory colorFactory = AbstractFactoryProducer.getFactory("Color");
// 获取颜色
assert colorFactory != null;
Color red = colorFactory.getColor("red");
red.fill();
Color blue = colorFactory.getColor("blue");
blue.fill();
}
}