工厂方法模式是简单工厂的抽象与扩展,如果单一的产品不能满足设计与需求,是否有其他模式对工厂方法进行再次扩展呢?所以就有了抽象工厂。
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
UML类图如下
从类图可以看出,产品1和产品2是两个抽象产品,为什么要是抽象的呢?因为它们可能有不同的实现(衍生类A或者B)。这就好比是两个系列的产品了。同样,核心工厂类下也有两个工厂子类用于创建不同类型的产品。
下面看个例子:现需要生产小汽车(car)和吉普车(jeep),会有不同的生产厂家如宝马和奔驰等。
首先依旧是产品类,此处有两类产品,小汽车和吉普车。
public interface Car {
public void drive();
}
public interface Jeep {
public void drive();
}
小汽车可能是宝马制造也有可能是奔驰制造,吉普车同理。
public class BWMCar implements Car {
public void drive() {
System.out.println("宝马小汽车在行驶。");
}
}
public class BenzCar implements Car {
public void drive() {
System.out.println("奔驰小汽车在行驶。");
}
}
public class BWMJeep implements Jeep {
public void drive(){
System.out.println("宝马吉普车在行驶。");
}
}
public class BenzJeep implements Jeep {
public void drive(){
System.out.println("奔驰吉普车在行驶。");
}
}
然后需要一个车辆的生产产商,用来生产小汽车和吉普车。
public interface VehicleFactory {
public Car createCar();
public Jeep createJeep();
}
同样,有了宝马和奔驰两家厂商来接单。
public class BWMFactory implements VehicleFactory {
public Car createCar() {
return new BWMCar();
}
public Jeep createJeep() {
return new BWMJeep();
}
}
public class BenzFactory implements VehicleFactory {
public Car createCar() {
return new BenzCar();
}
public Jeep createJeep() {
return new BenzJeep();
}
}
最后,我们就可以生产车辆了。
public class POC {
public static void main(String[] args) {
VehicleFactory vehicleFactory = new BWMFactory();
Car car = vehicleFactory.createCar();
Jeep jeep = vehicleFactory.createJeep();
car.drive();
jeep.drive();
vehicleFactory = new BenzFactory();
car = vehicleFactory.createCar();
jeep = vehicleFactory.createJeep();
car.drive();
jeep.drive();
}
}
可以看到,客户端调用代码时只需要切换具体的工厂实现类,下面的代码一模一样,但便是使用了另一套产品生产体系了(不同的厂商)。使用抽象工厂的第二个好处在于具体实例创建与客户端分离,客户端通过接口操作实例,产品具体类名也被具体工厂实现分离,不会出现在客户端代码中。