Java 让一个实例变量的验证依赖于另一个实例变量是否是一种不好的做法?

Java 让一个实例变量的验证依赖于另一个实例变量是否是一种不好的做法?,java,Java,让一个变量依赖于另一个变量的状态是否不好 例如,我有一个类Date,它的属性是day、month、和year。月和年可以在各自的设置器中独立验证,但日取决于月和/或年,即一个月/闰年的最大天数。我的方法是确保我的构造函数需要所有三个字段,并且它将在月和年之后调用天的setter 像这样的国家依赖性是不被鼓励的吗?我的类不是不可变的,所以我需要某种验证,我希望将验证封装在类本身中,而不是在外部进行 以下是我目前的代码: 上课日期{ 私人国际日; 私人整数月; 私人国际年; 公共字符串toStrin

让一个变量依赖于另一个变量的状态是否不好

例如,我有一个类
Date
,它的属性是
day
month
、和
year
。月和年可以在各自的设置器中独立验证,但
取决于
和/或
,即一个月/闰年的最大天数。我的方法是确保我的构造函数需要所有三个字段,并且它将在
之后调用
的setter

像这样的国家依赖性是不被鼓励的吗?我的类不是不可变的,所以我需要某种验证,我希望将验证封装在类本身中,而不是在外部进行

以下是我目前的代码:

上课日期{
私人国际日;
私人整数月;
私人国际年;
公共字符串toString(){
返回字符串.format(“%02d/%02d/%04d”,月、日、年);
}
公共整数getMonth(){
返回月份;
}
公共无效设置月(整数月){
//检查月份是否有效
如果(月<1 | |月>12){
抛出新的IllegalArgumentException(
格式(“%02d不是有效月份”,月份)
);
}否则{
本月=月;
}
}
公共int getYear(){
回归年;
}
公共年(国际年){
//检查年份是否有效
如果(年份<1900年|年份>2020年){
抛出新的IllegalArgumentException(
格式(“%04d不是有效年份”,年份)
);
}否则{
今年=年;
}
}
public int getDay(){
回归日;
}
公共无效设定日(整数日){
//检查日期是否有效
if(day<1 | | day>getMaxNumDaysInMonth(this.getMonth(),this.getYear()){
抛出新的非法访问异常(
String.format(“%02d不是有效的日期”,天)
);
}否则{
this.day=天;
}
}
日期(整数月、整数日、整数年){
设定月(月);
设定年份(年);
设定日(天);;
}
私人最终整数[]最大月日={
0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
/**
*获取一个月内的最大天数
*取决于月份和年份是否为闰年
*@param月
*@param年
*@返回
*/
私有整数getMaxNumDaysInMonth(整数月,整数年){
//检查日期是否有效
如果(年<1 | |月<1 | |月>12){
抛出新的IllegalArgumentException(
String.format(“%04d-%02d不是有效日期”、年、月)
);
}否则{
//如果一年是闰年,则调整二月
如果(月份==2){
如果(年){
返回最大月日[月];
}否则{
返回最大月天数[月]-1;
}
}否则{
返回最大月日[月];
}
}
}//结束getNumDaysInMonth
/**
*如果年份是闰年,则返回true
*否则返回false
*@param年
*@返回
*/
专用布尔值isLeapYear(整数年){
回报率(第%4年)=0&(第%100年!=0 | |第%400年==0);
}
}//结束日期类

参数验证始终是一个很好的主意,实际上有一些类专门为您做这类事情,使其更加容易

public void setMonth(整数月){

先决条件。checkArgument(month>=1&&month参数验证始终是一个好主意,实际上有一些类专门为您做这类事情,使它更容易

public void setMonth(整数月){

前提条件。checkArgument(month>=1&&month有趣的问题。我的想法是:您的对象实际上只有一个状态变量:日期。您必须通过提供三个单独的数字来设置该状态变量,这是实现的一个细节

您的验证应该拒绝将状态变量设置为某个伪值的任何尝试


如果您有一个包含多个状态变量的类,那么独立地验证它们对您的用户来说是很有帮助的。但不是针对日期。

有趣的问题。我的想法是:您的对象实际上只有一个状态变量:日期。您必须通过提供三个单独的数字来设置该状态变量,这是实现的一个细节反倾销

您的验证应该拒绝将状态变量设置为某个伪值的任何尝试


如果您有一个以上的状态变量,则您的用户可以独立地验证它们。但不是针对日期。

如杰森所提到的,考虑创建一个不可变类。现在您的实现不安全。用户可以通过在已经存在的STATE上使用不同的“SET”方法来破坏类不变量。例如,创建一个日期1月31日。然后将月份设置为2月。因为您只在那里检查有效月份,所以生成的日期将是2月31日。2020年2月29日也是如此,并将年份更改为2019年


如果您的类是不可变的,那么您只需要将所有有效性检查放在构造函数内,而不必担心在所有的“SET”方法中保存类不变量。

< P>如杰森所提到的,考虑创建一个不可变类。现在,您的实现不安全。用户可以通过使用不同的方法来破坏类不变量。已存在实例上的“set”方法。例如,创建日期为1月,