Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.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_Constructor - Fatal编程技术网

Java 将输入限制为构造函数,同时保持构造函数代码最少

Java 将输入限制为构造函数,同时保持构造函数代码最少,java,constructor,Java,Constructor,我被告知我必须创建一个接受货币和价值的money类。该值应存储为2个整数,一个表示美元值,另一个表示美分 *它应接受精确到小数点后两(2)位的十进制值* 所以我想我必须限制美分的值,这样它只能接受1到2位数的整数。现在,我的问题是,我的导师告诉我,在构造函数中做其他事情是不好的做法。如果不允许我对构造函数执行任何操作,那么我应该如何限制输入,除了: public class Money { Currency currency; int dollar; int cents;

我被告知我必须创建一个接受货币和价值的money类。该值应存储为2个整数,一个表示美元值,另一个表示美分

*它应接受精确到小数点后两(2)位的十进制值*

所以我想我必须限制美分的值,这样它只能接受1到2位数的整数。现在,我的问题是,我的导师告诉我,在构造函数中做其他事情是不好的做法。如果不允许我对构造函数执行任何操作,那么我应该如何限制输入,除了:

public class Money {
    Currency currency;
    int dollar;
    int cents;

    public Money(Currency currency, int dollar, int cents) {
        super();
        this.currency = currency;
        this.dollar = dollar;
        this.cents = cents;
    }
    ..... other code.....
}

关于我应该如何执行指示我的内容,还有其他想法吗?为什么这是一种不好的做法?有没有一种方法可以定义约束而不犯这种不好的做法呢?

您所做的是验证构造函数的输入。虽然一般来说,构造函数中的“其他东西”不是最优的,但在那里执行输入验证代码肯定是有保证的。在我看来,类似以下内容是一种很好的模式:

public Money(Currency currency, int dollar, int cents) {
    this.currency = currency;
    this.dollar = dollar;
    // validate that cents is 0 to 99
    if (cents < 0 || cents > 99) {
        throw new IllegalArgumentException("Invalid cents value: " + cents);
    }
    this.cents = cents;
}
公共货币(货币、整数美元、整数美分){
这个。货币=货币;
美元=美元;
//验证美分是否为0到99
如果(美分<0 | |美分>99){
抛出新的IllegalArgumentException(“无效的美分值:“+美分”);
}
这1.5美分=美分;
}

顺便说一句,在构造函数前面调用
super()
是没有意义的,除非。Java语言在幕后自动调用基类构造函数。

在构造函数中添加代码是错误的做法,你的导师是对的。 但添加方法调用则不是

因此,您可以将限制输入的操作封装在另一个方法中,并在超级函数之后立即调用它

但是,在我看来,最好的做法是在将输入限制传递给构造函数之前处理它

在单独的类中或在接口类后面的代码中解析输入。 避免在表示某个模型的类中使用代码操作,在本例中为“货币模型”

为什么这是不好的做法

在面向对象中,您必须编写类,以便它们不会执行更多必须知道的操作。在本例中,您的类表示对象money的模型。为什么模型需要自己解析传递给其构造函数的值? 知道了?最好的做法是为构造函数传递已经解析和限制的值,这样类就只需要存储这些值

例如,假设昨天您的约束发生了更改,您所要做的就是更改解析部分,而不必在Money类中编写代码

另一个例子是,有人必须使用您的money类,但它有自己的约束,他所要做的就是使用他的解析类,而不是在money类中更改您的解析类
希望有帮助。

我认为人们给出的最常见的原因是构造函数应该尽可能快地消除任何并发问题,并且万无一失,因为构造函数更难诊断

在您的情况下,简单的数字验证就可以了


但是,正如马塞洛所说的,您可以考虑编写验证函数并从构造函数调用它们,以确保一致性。

< p>如果美分值大于100,我将抛出<代码>异常。或者,除以100,将商和美元相加,剩余部分和美分相加。规范化和验证构造函数参数不是一个坏做法。

首先,如果使用构造函数得到无效对象,我认为验证并引发异常不是一个坏做法。
这就是说,看看你的要求,这可能是足够好的四舍五入美分。最后,您可以查看其他货币实现,例如,您不应该将美元和美分分开。只需记录美分的数字,然后除以100。并使用
biginger
,而不是
int
。此外,在其他货币中,价值不称为美元和美分。看@황현정: 使用32位整数(有符号或无符号)表示货币几乎总是一种代码味道。有很多坏掉的应用程序都犯了这样一个错误,即到目前为止或多或少“起作用”,但如果出现高通胀(这种情况已经发生在许多国家,而且可能再次发生),所有这些应用程序都会坏掉。使用64位原语(带符号或不带符号)或BigInteger。但是BigInteger会消耗太多内存,尤其是在循环和其他东西中使用时,正如我在《有效Java》中所读到的那样,此外,我的导师交给我的规范中有说明,所以我必须按照说明操作,否则我就注定要失败!哈哈。。我的想法是将美元转换成美分,美分转换成美元,而不是使用大整数D@Christoffer是的,我想知道美元和美分的事,但我猜他指的是,整部分(美元)和分数部分(美分),否则,在约束中加入货币是没有意义的。告诉老师,当他要求你用
int
表示货币价值时,互联网上有人说他在教可怕的做法。把他联系到这里。别忘了阅读Martin Fowler文章中的一个很好的例子:我真的不同意在课外进行“输入限制”的想法。如果类期望美分<100,那么它应该验证它。否则,它假定输入是正确的。这似乎是鲁莽的。我真的不同意下面的说法。“最佳实践是传递构造函数的值,这些值已经被解析和限制,因此类只需要存储这些值。”如果您谈论的是web表示对象或数据库对象,那么这可能是