运行时的Java对象选择
我对Java比较陌生,正在努力克服一个问题。。 我有一个基类,在这个例子中,我们称它为box,我还有3个box类继承了这个基类。原因是这3个盒子中的每一个都有不同的特点,使它们彼此区别开来。让我们假设: Box01只能由纸板制成,长度在15到30厘米之间。 Box02只能由铝制成,长度大于30厘米。 box03只能由塑料制成,长度小于100厘米 在有问题的程序中,用户不能具体选择盒子的类型,但必须提供他们的要求,并且程序必须回答说产品是否可行。因此,120厘米的塑料盒是不可能的,50厘米的纸板盒也是不可能的 我目前的解决方案是使用if语句,例如:运行时的Java对象选择,java,Java,我对Java比较陌生,正在努力克服一个问题。。 我有一个基类,在这个例子中,我们称它为box,我还有3个box类继承了这个基类。原因是这3个盒子中的每一个都有不同的特点,使它们彼此区别开来。让我们假设: Box01只能由纸板制成,长度在15到30厘米之间。 Box02只能由铝制成,长度大于30厘米。 box03只能由塑料制成,长度小于100厘米 在有问题的程序中,用户不能具体选择盒子的类型,但必须提供他们的要求,并且程序必须回答说产品是否可行。因此,120厘米的塑料盒是不可能的,50厘米的纸板盒
if(boxType == 'cardboard' && length >= 15 && length <= 30){
Box = new box01(boxType, length);
else if(boxType == 'aluminium' && length >= 30){
Box = new box02(boxType, length);
}
if(boxType=='carboard'&&length>=15&&length=30){
盒子=新的盒子02(盒子类型,长度);
}
我知道在这个简化的示例中,似乎没有必要使用额外的box类,但假设在实际版本中,box具有更多独特的特性,这些特性将反映在类属性和构造函数中
现在回答我的问题。这个特殊的方法在这里看起来还行,只有2个测试和几个ifs,但是我的程序有相当多的属性和更多的测试。对于我的程序来说,除了ifs之外,还有其他更复杂的方法来检测我的程序应该制作什么样的盒子吗
感谢所有花时间阅读、理解并发布回复的人。我确信解决方案比我想象的要简单得多。一个很好的方法是这样构造应用程序:
public interface BoxType(){ //Or BoxFactory or smth like that
public boolean isApplicable(int userInput1, String userInput2...); /// If you have more than 1-2 user input elements, create a special object (something like `UserInput`) with the user input/requirements and just pass it.
public Box buildBox(int userInput1, String userInput2...);
...
}
isapplicatable()
方法中定义其适用性条件,以及如何在buildBox()方法中构建它
这就是我所说的:
import java.util.Arrays;
import java.util.List;
enum Material {
CARDBOARD, ALUMINIUM, PLASTIC
}
class BoxProperties {
public Material material;
public double length;
}
abstract interface RuleSet {
public boolean isSatisfiedBy(BoxProperties props);
}
class MyRuleSet implements RuleSet {
private final Material material;
private final double[] length;
public MyRuleSet(Material mat, double minLength, double maxLength) {
this.material = mat;
this.length = new double[] {minLength, maxLength};
}
@Override
public boolean isSatisfiedBy(BoxProperties props) {
if (props.material != material) return false;
if (props.length < length[0] || props.length > length[1]) return false;
return true;
}
}
public class Box {
private static final List<? extends RuleSet> rules;
public final Material material;
public final double length;
private Box(BoxProperties props) {
this.material = props.material;
this.length = props.length;
}
public static Box createBox(BoxProperties props)
throws IllegalArgumentException {
for (RuleSet rs : rules) {
if (rs.isSatisfiedBy(props)) {
return new Box(props);
}
}
//XXX This should probably be made a checked exception
throw new IllegalArgumentException(
"No supported box type can fullfil the requests");
}
static {
rules = Arrays.asList(
new MyRuleSet(Material.CARDBOARD, 15, 30),
new MyRuleSet(Material.ALUMINIUM, 30, Double.POSITIVE_INFINITY),
new MyRuleSet(Material.PLASTIC, 0, 100)
);
}
}
然后,最好将
isWrappable()
添加到所有的框中,如果框永远不可包装,则返回false。这将简化调用者代码,而不会使被调用者代码变得特别复杂。了解工厂设计模式。这是一个链接,也许我弄错了,因为你有一个简单明了的例子,但我不确定你是否需要单独的类。可能只是一个工厂和一组规则,每种类型的框都是一个规则集类的不同实例。我把它变成了一个答案,这样我才能更清楚。为盒子单独设置类的原因是,例如:Box01可能无法包装礼物。这是特定于此框的,因此bool将传递给box01的构造函数true/false。Box02和Box03根本不应该能够进行礼品包装,因此它们无法访问该功能。我现在正在读工厂的书。我可以看到他们的帮助,但他们似乎仍然有足够的语句来定义规则?只是它会隐藏在工厂内部,而不是在主类等内部。@user2981060我认为没有办法避免If
语句。您必须在某个点检查要创建的对象<代码>工厂允许您在运行时创建对象。感谢您的回复!我会试试这个方法。值得注意的是,所有的盒子都至少有一个使它们独一无二的特征。例如,Box01可能有礼品包装,Box02可能有其他颜色,而Box03可能有透明的选项。这不是你所说的工厂吗:)是的,因此BoxFactory的注释:)虽然我认为,在这个简单的例子中,如果它被称为Type,它更容易理解。嗨,Cosmin SD,谢谢你的回复。今晚我将尝试实施这一方法和上述方法,看看哪一种最适合我。我会继续检查这里以及任何进一步的意见。我感谢大家的反馈。这很有帮助!
if (returnedBox instanceof MaybeWrappableBox && ((MaybeWrappableBox)returnedBox).isWrappable()) {
...
}