Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
运行时的Java对象选择_Java - Fatal编程技术网

运行时的Java对象选择

运行时的Java对象选择,java,Java,我对Java比较陌生,正在努力克服一个问题。。 我有一个基类,在这个例子中,我们称它为box,我还有3个box类继承了这个基类。原因是这3个盒子中的每一个都有不同的特点,使它们彼此区别开来。让我们假设: Box01只能由纸板制成,长度在15到30厘米之间。 Box02只能由铝制成,长度大于30厘米。 box03只能由塑料制成,长度小于100厘米 在有问题的程序中,用户不能具体选择盒子的类型,但必须提供他们的要求,并且程序必须回答说产品是否可行。因此,120厘米的塑料盒是不可能的,50厘米的纸板盒

我对Java比较陌生,正在努力克服一个问题。。 我有一个基类,在这个例子中,我们称它为box,我还有3个box类继承了这个基类。原因是这3个盒子中的每一个都有不同的特点,使它们彼此区别开来。让我们假设: Box01只能由纸板制成,长度在15到30厘米之间。 Box02只能由铝制成,长度大于30厘米。 box03只能由塑料制成,长度小于100厘米

在有问题的程序中,用户不能具体选择盒子的类型,但必须提供他们的要求,并且程序必须回答说产品是否可行。因此,120厘米的塑料盒是不可能的,50厘米的纸板盒也是不可能的

我目前的解决方案是使用if语句,例如:

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之外,还有其他更复杂的方法来检测我的程序应该制作什么样的盒子吗


感谢所有花时间阅读、理解并发布回复的人。我确信解决方案比我想象的要简单得多。

一个很好的方法是这样构造应用程序:

  • 使用具有de基本实现的接口或抽象类:

    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()) {
        ...
    }