Проверка полей в конструкторе и установщике считается плохим избыточным кодом?

У меня есть следующий класс:

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 совместно используют одну и ту же проверку для своих полей с конструктором. Является ли это избыточным кодом, который может вызвать проблемы в будущем (например, если кто-то отредактирует установщик, чтобы разрешить 0 для идентификатора и запретить -1 вместо, но не изменил конструктор)?, Должен ли я использовать закрытый метод для проверки и делиться им между конструктором и установщиком, что кажется слишком большим, если полей много.

Примечание. Вот почему я не использую сеттеры в конструкторе. /questions/15599664/vyizov-settera-iz-konstruktora/15599675#15599675

4 ответа

Вот пересмотренный код:

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");
        }
    }

}

Я рекомендую вам определить один метод для каждого поля как isValid() и затем вызовите тот же метод в вашем сеттере, как и в конструкторе.

Если вы сделаете Project неизменный, это устранит избыточный код. но сейчас я думаю, что явно выбрасывать исключения как в конструкторе, так и в методе мутатора - это нормально.

и я бы не стал вызывать методы-мутаторы в конструкторе по многим причинам, включая это. Кроме того, я бы удалил код проверки в методе доступа... это не обязательно.

Я бы сказал, да. Вместо этого просто вызовите сеттеры из вашего конструктора:

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, В противном случае будет сложно отследить ошибки - вы захотите поймать недопустимое имя, как только оно появится, а не когда оно будет использовано (что может быть гораздо позже).

Другие вопросы по тегам