概述
本文将解释Java中的工厂设计模式:工厂方法和抽象工厂,并用实际例子来说明如何实现该模式。
工厂方法模式
比如为一家汽车制造商开发一款应用程序。起初,该客户制造的车辆仅使用燃油发动机。因此,为了遵循单一责任原则(SRP)和开闭原则(OCP),我们使用工厂方法设计模式。
工厂方法模式通过将产品的构造代码与使用该产品的代码分离来解耦合。
首先,在我们的示例应用程序中,定义了MotorVehicle接口。这个接口只有一个方法build(),用于制造特定的机动车辆:
public interface MotorVehicle {
void build();
}
下一步是实现MotorVehicle接口的具体类。我们创造了两种类型:摩托车和汽车:
public class Motorcycle implements MotorVehicle {
@Override
public void build() {
System.out.println("Build Motorcycle");
}
}
public class Car implements MotorVehicle {
@Override
public void build() {
System.out.println("Build Car");
}
}
然后,我们创建MotorVehicleFactory类。这个类负责创建每个新的车辆实例。它是一个抽象类,因为它为特定的工厂制造特定的车辆:
public abstract class MotorVehicleFactory {
public MotorVehicle create() {
MotorVehicle vehicle = createMotorVehicle();
vehicle.build();
return vehicle;
}
protected abstract MotorVehicle createMotorVehicle();
}
方法create()调用抽象方法createMotorVehicle()来创建特定类型的机动车辆,之前我们具有两种类型的摩托车和汽车:
public class MotorcycleFactory extends MotorVehicleFactory {
@Override
protected MotorVehicle createMotorVehicle() {
return new Motorcycle();
}
}
public class CarFactory extends MotorVehicleFactory {
@Override
protected MotorVehicle createMotorVehicle() {
return new Car();
}
}
我们的应用程序是使用工厂方法模式设计,现在就可以随心所欲地增加新的机动车辆。最后,我们看看使用UML表示法的最终设计是什么样子的:
抽象工厂模式
比如两家新的汽车品牌公司对我们上面设计的系统感兴趣:NextGen和FutureVehicle。这些新公司不仅生产纯燃料汽车,还生产电动汽车。每家公司都有自己的汽车设计,为了解决这些问题,我们可以使用抽象工厂模式,将产品创建代码集中在一个地方。UML表示为:
我们已经有了MotorVehicle接口。此外,必须添加一个接口来表示电动汽车:
public interface ElectricVehicle {
void build();
}
接下来,我们创建抽象工厂。该类是抽象的,因为创建对象的责任将由具体工厂承担。这种行为遵循OCP和SRP:
public abstract class Corporation {
public abstract MotorVehicle createMotorVehicle();
public abstract ElectricVehicle createElectricVehicle();
}
FutureVehicle公司生产的车辆:
public class FutureVehicleMotorcycle implements MotorVehicle {
@Override
public void build() {
System.out.println("Future Vehicle Motorcycle");
}
}
public class FutureVehicleElectricCar implements ElectricVehicle {
@Override
public void build() {
System.out.println("Future Vehicle Electric Car");
}
}
NexGen公司做了同样的事情:
public class NextGenMotorcycle implements MotorVehicle {
@Override
public void build() {
System.out.println("NextGen Motorcycle");
}
}
public class NextGenElectricCar implements ElectricVehicle {
@Override
public void build() {
System.out.println("NextGen Electric Car");
}
}
FutureVehicle工厂:
public class FutureVehicleCorporation extends Corporation {
@Override
public MotorVehicle createMotorVehicle() {
return new FutureVehicleMotorcycle();
}
@Override
public ElectricVehicle createElectricVehicle() {
return new FutureVehicleElectricCar();
}
}
接下来是另一个NexGen工厂:
public class NextGenCorporation extends Corporation {
@Override
public MotorVehicle createMotorVehicle() {
return new NextGenMotorcycle();
}
@Override
public ElectricVehicle createElectricVehicle() {
return new NextGenElectricCar();
}
}
我们使用抽象工厂模式完成了实现。以下是我们自定义实现的UML图:
结论
工厂方法使用继承作为设计工具。而抽象工厂使用委托。
工厂方法依赖于派生类来实现,基类提供预期的行为,它是在方法上,而不是在类上。而抽象工厂被应用于一个类。
两者都遵循OCP和SRP,产生了松散耦合的代码,并为以后的更改扩展提供了更大的灵活性。