Пример рефакторинга «извлечение класса» из кода для работы с веб-формой


Исходный код

function validateForm(form) {
    if (isNotEmpty(form.name1)) {
        if (isNotEmpty(form.name2)) {
            if (isNotEmpty(form.eMail)) {
                if (isEMailAddr(form.eMail)) {
                    if (isChosen(form.continent)) {
                        if (isValidRadio(form.accept)) {
                            return true;
                        }
                    }
                }
            }
        }
    }
    return false;
}

Что не так в исходном коде

Мне колоссально нравится, что знания о реализации каждого вида валидации спрятаны в отдельные функции — вот образец идеального разделения ответственностей. Однако лесенка из операторов if всё-таки выглядит устрашающе.

Как мелкий недочёт можно отметить название функции: это не функция-команда, а функция-запрос, ей больше подойдёт название isFormValid.

Более значимый недочёт: эта функция является завистливой. В идеале объект формы должен являться экземпляром класса-формы (причём конкретно этой формы), а функция должна являться методом этого класса.

Как лучше всего отрефакторить исходный код

class UserSignupForm {
    isValid() {
        return (
                           isNotEmpty(this.name1)
                    && isNotEmpty(this.name2)
                    && isNotEmpty(this.eMail)
                    && isEMailAddr(this.eMail)
                    && isChosen(this.continent) 
                    && isValidRadio(this.accept)
        );
    }
}

Теория