例如,考虑以下两个setter:
bool setMonth(int month) {
bool valid = false;
if (month > 0 && month < 12) {
this->month = month;
valid = true;
}
return valid;
}
与
void setMonth(int month) {
if (month > 0 && month < 12) {
this->month = month;
}
}
第一个让类的客户端明确知道集合是否失败。这被认为是好习惯吗?
答案 0 :(得分:5)
我不这么认为。这意味着无论何时设置某些东西,都必须检查操作是否成功 对于可读性和逻辑,我认为提出异常是一个更好的主意 我发现:
/*program stuff*/
try{
YourObject.setMonth(0);
/* other stuff*/
}catch YourException{
/* recovery*/
}
更清洁:
/*program stuff*/
if(!YourObject.setMonth(0)){
/*recovery*/
}else{
/*stuff*/
}
在逻辑(我会说哲学)和可读性方面。
答案 1 :(得分:3)
有人可能会说使用boolean
作为返回类型并没有伤害。在最糟糕的情况下,你只需忽略支票。
另一个人可能会争辩说,抛出异常更优雅,也更具信息性(如Java的IllegalArgumentException
或Python的ValueError
),但这可能导致更多的“麻烦”,因为必须处理异常从客户代码中这样或那样。
第三种方法,如果您需要确保插入的值绝对正确,则将允许的值封装在结构实体中,例如类,枚举或命名空间。
Java中的一个例子是:
public void setMonth(Month month){
this.month = month; // member month is now of type Month
}
public enum Month{
JANUARY(1),
FEBRUARY(2),
MARCH(3),
APRIL(4),
MAY(5),
JUNE(6),
JULY(7),
AUGUST(8),
SEPTEMBER(9),
OCTOBER(10),
NOVEMBER(11),
DECEMBER(12)
private int n;
private Month(int n){
this.n = n;
}
}
以及使用它的方式是:
someObject.setMonth(Month.FEBRUARY);
(您可以使用C ++中的命名空间实现相同的功能。)
答案 2 :(得分:2)
当您想要跟踪插入到它们的无效数据时,最好在setter中使用异常。在这种情况下,方法的签名是:
//throw exception when month is out of range
void setMonth(int month) throws InvalidMonthNumberException;
如果你想在月份超出范围时设置默认数据,请在javadoc中描述。
/*
* If month < 1 or month > 12 default month (1) accepted
*/
void setMonth(int month);
答案 3 :(得分:1)
如果是java(你标记了两种语言),那么最佳做法是从setter返回void。如果设置值失败,则抛出异常。对于您的情况,您应该抛出IllegalArgumentException
月份设置器。