验证构造函数和setter中的字段是否被视为错误的冗余代码?

时间:2012-09-01 16:28:24

标签: java coding-style getter-setter

我有以下课程:

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

4 个答案:

答案 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。另外,我会删除访问器方法中的验证代码......这不是必需的。