对于具有不同参数的构造函数,工厂方法不够灵活,还是我遗漏了什么?

时间:2017-01-13 15:41:49

标签: java factory

请考虑以下两个类:

public class Audi implements Car {
private String color;
private int turnAssistLevel;

public Audi() {
}

public Audi(String color) {
    this.color = color;
}

public Audi(String color, int turnAssistLevel) {
    this.color = color;
    this.turnAssistLevel = turnAssistLevel;
}

public String getColor() {
    return color;
}

public void setColor(String color) {
    this.color = color;
}

public int getTurnAssistLevel() {
    return turnAssistLevel;
}

public void setTurnAssistLevel(int turnAssistLevel) {
    this.turnAssistLevel = turnAssistLevel;
}
}

public class Bmw implements Car {
private String color;
private boolean hasXDrive;

public Bmw() {
}

public Bmw(String color) {
    this.color = color;
}

public Bmw(String color, boolean hasXDrive) {
    this.color = color;
    this.hasXDrive = hasXDrive;
}

public String getColor() {
    return color;
}

public void setColor(String color) {
    this.color = color;
}

public boolean isHasXDrive() {
    return hasXDrive;
}

public void setHasXDrive(boolean hasXDrive) {
    this.hasXDrive = hasXDrive;
}
}

我想用工厂方法写一些工厂:

假设我想要一些工厂方法来返回空车。容易做到:

public interface CarFactory {
public Car makeCar();
}

作为实施:

public class BmwCarFactory implements CarFactory {

public Car makeCar() {
    return new Bmw();
}
}

我能为奥迪做的一切。

现在,我想要一辆有颜色的汽车。在我看来,我需要定义一个知道如何用颜色做汽车的工厂:

public interface CarWithColorFactory {
Car makeCar(String color);
}

现在制作一个有颜色的宝马:

public class BmwWithColorCarFactory implements CarWithColorFactory {
public Car makeCar(String color) {
    return new Bmw(color);
}
}

奥迪也一样。

但是现在,我说我需要用颜色和xDrive做一个宝马。或者是具有颜色和turnAssistLevel的奥迪。我如何使用工厂方法???

使用简单的工厂我可能会这样做:

public class SimpleCarFactory {

public Car makeBmw(String color, boolean hasXDrive) {
    return new Bmw(color, hasXDrive);
}

public Car makeAudi(String color, int turnAssistLevel) {
    return new Audi(color, turnAssistLevel);
}
}

那么如何使用工厂方法呢?

亲切的问候,

2 个答案:

答案 0 :(得分:0)

如何使用builder呢?

通过这种方式,您可以拥有允许您独立设置每个属性的方法,并提供合适的默认值,以便在不需要时不需要明确指定它们。

e.g。

BuilderFor.type("Audi").withColor("Red").withTurnAssist().build();

所以上面有效地使用工厂为您提供适当的构建器

答案 1 :(得分:0)

工厂方法通过子类化提供配置。因此,我发现在子类中进行所有配置决策更简单。在实践中,这意味着工厂方法将是无效的(不带参数)。***

工厂方法返回抽象产品,不考虑该产品的具体属性。此行为与编程到接口的设计原则一致。例如,需要驱动Car的程序应该取决于Car接口。它不应该依赖于配备XDrive的黑色宝马。 BMW子类(可能还有BMW_XDrive子类)的责任是配置这样一个具体的产品。

重申:工厂方法(又名创建者)的使用者不配置产品。以下是使用者(FactoryMethod)需要驱动Car并指定方法rentCar()以便子类提供该依赖关系的示例。这两个子类各自配置一个特定的具体产品,但消费者只需获得Car

public abstract class FactoryMethod {
    abstract Car rentCar();

    public void driveCar() {
        Car car = rentCar();
        car.drive();
    }

    public static class AudiFactoryMethod extends FactoryMethod {
        @Override
        Car rentCar() {
            return new Audi("red", 5);
        }
    }

    public static class BmwFactoryMethod extends FactoryMethod {
        @Override
        Car rentCar() {
            return new BMW("black", true);
        }
    }

    public static void main(String... args) {
        new AudiFactoryMethod().driveCar();
        new BmwFactoryMethod().driveCar();
    }
}

作为另一个例子,考虑一个依赖于List的类。它可以通过添加抽象方法getList()通过工厂方法获取该List。这个类可能有一个LinkedList子类和一个ArrayList子类。

***是的,我知道GoF描述了参数化工厂方法的使用;但这些都不可避免地违反了开放原则。正如Josh Bloch所描述的那样,静态工厂方法在这种情况下更简单,更直接。