工厂方法模式是简单工厂的抽象与扩展,如果单一的产品不能满足设计与需求,是否有其他模式对工厂方法进行再次扩展呢?所以就有了抽象工厂。
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
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(); } }
可以看到,客户端调用代码时只需要切换具体的工厂实现类,下面的代码一模一样,但便是使用了另一套产品生产体系了(不同的厂商)。使用抽象工厂的第二个好处在于具体实例创建与客户端分离,客户端通过接口操作实例,产品具体类名也被具体工厂实现分离,不会出现在客户端代码中。