1

我创建了一个BicycleProducer具有不同实现的接口:OffroadBicycleProducer等等FastBicycleProducer

这些工厂中的每一个都需要许多参数才能生产自行车。我想将这些属性封装在一个类中并将其传递给produce方法。然而,自行车需要不同的属性——有些可能是相同的——我想知道如何正确地做到这一点。在我的接口中,BicycleProducer我目前有一个名为的方法produce,它接受一个参数,该参数BicycleProducingContext是一个具有所有公共属性的接口。然后你有实现它的实现,并根据它是什么类型的自行车添加必要的属性。然后你需要在produce方法中强制转换它......但我不知道。我觉得这似乎有点狡猾(可能不是)。

这是一个很好的方法还是我应该以另一种方式来做?

public interface BicycleProducer {
    void produce(BicycleProducingContext context);
}

public class OffroadBicycleProducer implements BicycleProducer {

    public void produce(BicycleProducingContext context) {
        context = (OffroadBicycleProducingContext) context;
    }
}

public interface BicycleProducingContext {

    int numberOfBicycles();
    void brand(String brand);
}

public class OffroadBycycleProducingContext implements BicycleProducingContext {

    //..
}
4

1 回答 1

1

我发现您提出的设计有两点有点尴尬:

  1. 对我来说,看起来您可能根本不需要工厂(即您的Producer课程)。当您需要构造一个在编译时类型未知的对象时,工厂非常有用。但是由于您正在考虑为每种类型的自行车(例如OffroadBicycleProducer)设置单独的工厂类,我假设您确实知道要提前构建什么样的对象。

  2. 使用上下文类使参数传递不那么难看是一个好主意,但是如果您开始为每种类型的自行车创建单独的上下文类,那么您最终会陷入尴尬的境地,即必须知道要构造哪个上下文以及哪些数据它需要 - 如果您拥有所有这些,您不妨跳过中间步骤并Bicycle立即构建。

如果我假设您确实知道需要提前构造什么样的对象是正确的,那么我将不使用工厂,而是使用构建器模式,或者使用普通的旧构造器。构造函数方法可能类似于以下内容:

public abstract class Bicycle {
    private int year;
    private String color;

    public Bicycle(BicycleProducingContext context) {
        this.year = context.getYear();
        this.color = context.getColor();
    }
}

public class OffroadBicycle extends Bicycle {
    private String terrainType;

    public OffroadBicycle(BicycleProducingContext context) {
        super(context);
        this.terrainType = context.getTerrainType();
    }
}

public class FastBicycle extends Bicycle {
    private int maxSpeed;

    public FastBicycle(BicycleProducingContext context) {
        super(context);
        this.maxSpeed = context.getMaxSpeed();
    }
}

如果在运行时之前不知道Bicycle要构造什么类型,那么可以将上述方法与单个工厂一起使用。例如:

public class BicycleFactory {
    public static Bicycle constructBicycle(BicycleProducingContext context) {
        if (context.getBicycleType().equals("OffroadBicycle")) {
            return new OffroadBicycle(context);
        } else if (context.getBicycleType().equals("FastBicycle")) {
            return new FastBicycle(context);
        } else {
            throw new IllegalArgumentException("Encountered unrecognized Bicycle type: " + context.getBicycleType());
        }
    }
}

我希望我不会过度简化您的用例,但在我看来,上面的内容应该可以完成您正在寻找的内容。

于 2012-11-08T01:42:50.133 回答