多种工厂方法与单一方法

时间:2013-07-08 16:37:07

标签: java class factory factory-method construction

对所有实例使用单个工厂方法和通用构造函数是否更好,然后填充实例?或者应该使用多个工厂方法和构造函数?每种方法有哪些优点?

例如(选项#1 ):

VehicleFactory {
  Vehicle createVehicle(int serialNo);
}

// assuming that Car and Plane are of type Vehicle:

Car car = (Car)VehicleFactory.createVehicle(serialNo1);
car.setCarSpecificField1(...);
car.setCarSpecificField2(...);

Plane plane = (Plane)VehicleFactory.createVehicle(serialNo2);
plane.setPlaneSpecificField1(...);
plane.setPlaneSpecificField2(...);

这里Plane和Car将有一个简单的通用构造函数,但需要多个setter和getter。调用者必须填充实例。

或(选项#2 ):

VehicleFactory {
  Car createCar(int serialNo, CarSpecificField1 field1, CarSpecificField2 field2, ...)
  Plane createPlane(int serialNo, PlaneSpecificField1 field1, PlaneSpecificField2, ...)
}

Car car = VehicleFactory.createCar(serialNo1, carSpecificField1, ...);
Plane plane = VehicleFactory.createPlane(serialNo2, planeSpecificField1, ...);

在这里,我们不需要getter和setter,但每个实例都需要不同的构造函数。

2 个答案:

答案 0 :(得分:1)

您可以执行类似的操作,但请记住,从超类继承构建器方法意味着您必须首先设置所有特定于汽车的字段(或进行大量投射)。

abstract class Vehicle {
    Object vehicleSpecificField1, vehicleSpecificField2;
}

class Car extends Vehicle {
    Object carSpecificField;

    Car(final Object vehicleSpecificField1, final Object vehicleSpecificField2, final Object carSpecificField) {
        this.vehicleSpecificField1 = vehicleSpecificField1;
        this.vehicleSpecificField2 = vehicleSpecificField2;
        this.carSpecificField = carSpecificField;
    }
}

abstract class VehicleBuilder<E extends Vehicle> {
    Object vehicleSpecificField1, vehicleSpecificField2;

    public VehicleBuilder<E> vehicleSpecificField1(final Object vehicleSpecificField1) {
        this.vehicleSpecificField1 = vehicleSpecificField1;
        return this;
    }

    public VehicleBuilder<E> vehicleSpecificField2(final Object vehicleSpecificField2) {
        this.vehicleSpecificField2 = vehicleSpecificField2;
        return this;
    }

    abstract E create();

}

class CarBuilder extends VehicleBuilder<Car> {
    Object carSpecificField;

    public CarBuilder carSpecificField(final Object carSpecificField) {
        this.carSpecificField = carSpecificField;
        return this;
    }

    @Override
    Car create() {
        return new Car(vehicleSpecificField1, vehicleSpecificField2, carSpecificField);
    }
}

public static void main(String[] args) {
    Car car = new CarBuilder().carSpecificField("car").vehicleSpecificField1("foo").vehicleSpecificField2("bar").create();
}

答案 1 :(得分:0)

这是另一种方法:

VehicleFactory<E extends Vehicle> {
    E getVehicle(int serialNo, VehicleProperty<E> ... args);
}
CarFactory extends VehicleFactory<Car>{
    @Override
    Car getVehicle(int serialNo, VehicleProperty<Car> ... args);
}

VehicleProperty<E extends Vehicle>{ /* getters and setters */}
CarProperty extends VehicleProperty<Car>{}