哪个实现更好(DRY 和 KISS)
Which implementation is better (DRY and KISS)
下面我有 return 月份名称的方法。在第一个实现中,我使用 switch/case,此方法较长,验证在最后一行。在第二个上,我在第一行进行了验证,而不是 switch/case 我用月份名称声明了 table。
当我考虑 KISS 和 DRY 原则时,哪个更好?
public String getMonthName(int month) {
switch (month) {
case 1:
return "January";
case 2:
return "February";
case 3:
return "March";
case 4:
return "April";
case 5:
return "May";
case 6:
return "June";
case 7:
return "July";
case 8:
return "August";
case 9:
return "September";
case 10:
return "October";
case 11:
return "November";
case 12:
return "December";
default:
throw new IllegalArgumentException("month must be in range 1 to 12");
}
}
或者这一个?
public String getMonthNameNew(int month) {
if ((month < 1) || (month > 12)) throw new IllegalArgumentException("month must be in range 1 to 12");
String[] months = {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
return months[month - 1];
}
对于理论上的例子,两者都可以(我更喜欢第一个,因为它显示了一行中数字与字符串的 "mapping"。选项 2 要求您了解 months[month - 1];
会为你做。正如评论中所建议的,"most straight forward" 解决方案将围绕一个月 enum 构建,并使该月份名称成为该枚举的一个字段。
在现实世界中,这两个例子都不够。
在这里您将专注于 "dont repeat yourself" 并查看现有的库 class 来为您做这件事。
我觉得第二个更容易阅读。它更短,并带有前提条件检查,可立即告诉您允许使用哪些值。在第一个示例中,您必须通过整个方法体才能理解。
综上所述,方法应使用 java.time.Month
编写为:
public String getMonthNameNew(int month) {
return Month.of(month).getDisplayName(TextStyle.FULL, Locale.ENGLISH);
}
像这样的情况,最好列出 pro/cons。
示例 1:
亲:
- 容易理解
- 可读
缺点:
- 难以扩展(您如何 return 不同语言的月份名称?)。
- 其他 Java API 使用月份值 0 到 11。
- 几乎是第二个例子的两倍。
示例 2:
亲:
- 紧凑
- 如果稍微更改代码,您可以从不同的来源(属性文件、数据库)填充数组。
- 灵活
缺点:
- 聪明。代码取决于数据集中没有间隙这一事实。虽然在这种情况下确实如此,但在其他情况下可能就不那么明确了。
- 其他 Java API 使用月份值 0 到 11(同上)。
如果没有额外要求,我看不到明显的赢家。
就像我在评论中所说的那样,您可以通过枚举 class 来做到这一点。
public enum Months {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
}
下面我有 return 月份名称的方法。在第一个实现中,我使用 switch/case,此方法较长,验证在最后一行。在第二个上,我在第一行进行了验证,而不是 switch/case 我用月份名称声明了 table。
当我考虑 KISS 和 DRY 原则时,哪个更好?
public String getMonthName(int month) {
switch (month) {
case 1:
return "January";
case 2:
return "February";
case 3:
return "March";
case 4:
return "April";
case 5:
return "May";
case 6:
return "June";
case 7:
return "July";
case 8:
return "August";
case 9:
return "September";
case 10:
return "October";
case 11:
return "November";
case 12:
return "December";
default:
throw new IllegalArgumentException("month must be in range 1 to 12");
}
}
或者这一个?
public String getMonthNameNew(int month) {
if ((month < 1) || (month > 12)) throw new IllegalArgumentException("month must be in range 1 to 12");
String[] months = {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
return months[month - 1];
}
对于理论上的例子,两者都可以(我更喜欢第一个,因为它显示了一行中数字与字符串的 "mapping"。选项 2 要求您了解 months[month - 1];
会为你做。正如评论中所建议的,"most straight forward" 解决方案将围绕一个月 enum 构建,并使该月份名称成为该枚举的一个字段。
在现实世界中,这两个例子都不够。
在这里您将专注于 "dont repeat yourself" 并查看现有的库 class 来为您做这件事。
我觉得第二个更容易阅读。它更短,并带有前提条件检查,可立即告诉您允许使用哪些值。在第一个示例中,您必须通过整个方法体才能理解。
综上所述,方法应使用 java.time.Month
编写为:
public String getMonthNameNew(int month) {
return Month.of(month).getDisplayName(TextStyle.FULL, Locale.ENGLISH);
}
像这样的情况,最好列出 pro/cons。
示例 1:
亲:
- 容易理解
- 可读
缺点:
- 难以扩展(您如何 return 不同语言的月份名称?)。
- 其他 Java API 使用月份值 0 到 11。
- 几乎是第二个例子的两倍。
示例 2:
亲:
- 紧凑
- 如果稍微更改代码,您可以从不同的来源(属性文件、数据库)填充数组。
- 灵活
缺点:
- 聪明。代码取决于数据集中没有间隙这一事实。虽然在这种情况下确实如此,但在其他情况下可能就不那么明确了。
- 其他 Java API 使用月份值 0 到 11(同上)。
如果没有额外要求,我看不到明显的赢家。
就像我在评论中所说的那样,您可以通过枚举 class 来做到这一点。
public enum Months {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
}