我创建了一个BicycleProducer
接口,它有不同的实现:OffroadBicycleProducer
,FastBicycleProducer
等等。
这些工厂中的每一个都需要许多参数来生产自行车。我想将这些属性封装在一个类中,并将其传递给produce
方法。然而,自行车需要不同的属性 - 有些可能是相同的 - 我想知道如何正确地做到这一点。在BicycleProducer
的接口中,我目前有一个名为produce
的方法,它接受一个参数BicycleProducingContext
,它是一个包含所有公共属性的接口。然后你有实现它的实现,并根据它的自行车类型添加necassary属性。然后你需要用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 {
//..
}
答案 0 :(得分:1)
我发现你提出的设计有两点尴尬:
对我来说,看起来你可能根本不需要工厂(即你的Producer
课程)。当您需要构造一个在编译时未知类型的对象时,工厂非常有用。但是既然你想为每种类型的自行车设置单独的工厂类(例如OffroadBicycleProducer
),我认为你确实知道你想要提前建造什么样的物体。
使用上下文类使参数传递不那么难看是一个好主意,但是如果你开始为每种类型的自行车创建单独的上下文类,那么你最终会陷入尴尬的境地,必须知道哪个上下文构造以及它需要什么数据 - 如果你有所有这些,你也可以跳过中间步骤并立即构建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());
}
}
}
我希望我不会过度简化您的用例,但在我看来,上述内容应该可以实现您的目标。