我有以下课程:
public class Project {
private int id;
private String name;
public Project(int id, String name) {
if(name == null ){
throw new NullPointerException("Name can't be null");
}
if(id == 0 ){
throw new IllegalArgumentException("id can't be zero");
}
this.name = name;
this.id = id;
}
private Project(){}
public int getId() {
return id;
}
public void setId(int id) {
if(id == 0 ){
throw new IllegalArgumentException("id can't be zero");
}
this.id = id;
}
public String getName()
return name;
}
public void setName(String name) {
if(name == null ){
throw new NullPointerException("Name can't be null");
}
this.name = name;
}
}
如果您注意到setName和setId与构造函数的字段共享相同的验证。这个冗余代码是否可能导致将来出现问题(例如,如果有人编辑setter以允许id为0并防止-1而不是更改构造函数)? 。我是否应该使用私有方法进行检查并在构造函数和setter之间共享它,如果有很多字段,这似乎太多了。
注意:这就是我不在构造函数中使用setter的原因。 https://stackoverflow.com/a/4893604/302707
答案 0 :(得分:2)
以下是修订后的代码:
public class Project {
private int id;
private String name;
public Project(int id, String name, Date creationDate, int fps, List<String> frames) {
checkId(id);
checkName(name);
//Insted of lines above you can call setters too.
this.name = name;
this.id = id;
}
private Project(){}
public int getId() {
return id;
}
public void setId(int id) {
checkId(id);
this.id = id;
}
public String getName()
return name;
}
public void setName(String name) {
checkName(name);
this.name = name;
}
private void checkId(int id){
if(id == 0 ){
throw new IllegalArgumentException("id can't be zero");
}
}
private void checkName(String name){
if(name == null ){
throw new NullPointerException("Name can't be null");
}
}
}
答案 1 :(得分:1)
我建议你应该为每个字段定义一个方法isValid()
,然后在你的setter和Constructor中调用相同的方法。
答案 2 :(得分:0)
我会说是的。而不是那样,只需从构造函数中调用setter:
public Project(int id, String name, Date creationDate, int fps, List<String> frames) {
setName(name);
setId(id);
// other stuff with creationDate, fps and frames?
}
此外,您不应在name
中检查空getName
- 在setName
中执行此操作。否则,bug很难被追踪 - 你想要在它进入时立即捕获无效名称,而不是在它被使用时(可能会更晚)。
答案 3 :(得分:0)
如果你使Project
不可变,它将消除冗余代码。但是现在,我认为在构造函数和mutator方法中明确地抛出异常是可以的。
我不会在构造函数中调用mutator方法有很多原因,包括this。另外,我会删除访问器方法中的验证代码......这不是必需的。