Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Сборщики JS: Объектно-ориентированный дизайн

Иногда создание объекта — это сложный и даже многоэтапный процесс с дополнительными условиями. К таким объектам относятся валидаторы, реализованные в объектном стиле.

Валидация — это процесс проверки данных на корректность по заданным условиям. А валидатор — это что-то, выполняющее данную проверку.

В программировании валидация встречается на каждом шагу. Мы так или иначе работаем с формами или данными, отправляемыми по API. Все эти данные присылаются пользователями или внешними системами и автоматически считаются недоверенными. Перед тем как работать с ними, сначала нужно убедиться что они "валидные", то есть соответствуют нашим требованиям. Например, если мы говорим про емейл пользователя, то для большинства форм регистрации он должен быть не пустой и должен соответствовать формату емейлов.

Самый простой способ сделать валидацию, это выполнить ручную проверку:

if (data.email === '') {
  errors.push('емейл пустой');
}

// гипотетическая функция проверки формата
if (!hasEmailFormat(data.email)) {
  errors.push('емейл имеет неверный формат');
}

Нетрудно представить, как разрастется этот код для большой формы со множеством правил. У такого способа есть и другие проблемы. Он не позволяет легко переиспользовать правила для разных форм и проектов. Кроме того, многие проверки придется либо реализовывать самостоятельно, либо искать готовые библиотеки для них. Например, для проверки корректности ссылок, адресов и других вещей.

Yup

В JavaScript для выполнения валидации очень популярна библиотека yup. Посмотрите на пример, эквивалентный проверкам выше:

import * as yup from 'yup';

const schema = yup.string().required().email();

schema.validateSync(''); // ValidationError: this is a required field
schema.validateSync('wrongemail'); // ValidationError: this must be a valid email
schema.validateSync('support@hexlet.io'); // возвращает само значение

Принцип работы этой библиотеки следующий. С помощью цепочки методов формируется схема валидации. В эту цепочку входят различные условия, которые должны выполняться по принципу объединения. То есть для успешной валидации должны выполниться все условия. Сами условия зависят от того, какого типа проверяемые данные, поэтому в начале вызывается метод, задающий тип, и затем вызываются методы, которые относятся к данному типу данных:

// методы positive() и integer() есть только у number
const schema1 = yup.number().required().positive().integer();

// массив должен содержать от 5 до 10 элементов
const schema2 = yup.array().min(5).max(10);

Во всех этих ситуациях наша задача – сформировать правильную схему под конкретную задачу. Затем эту схему можно использовать множество раз на разных данных. Подобный способ формирования объекта-схемы называется сборкой, а сам объект – сборщиком. По большому счету это небольшая разновидность использования текучего интерфейса. Чем он удобен? С его помощью просто собирать даже сложные проверки, используя очень понятную механику объединения вызовов. Код при этом получается простым и понятным.

Из дополнительных плюсов – наличие готовых сообщений об ошибках для всех встроенных проверок. При необходимости их можно поменять для конкретной схемы, просто передав текст в методы проверок:

// Замена идет только для данной схемы
const schema1 = yup.string().required('Пусто!');

const schema2 = yup.string().required(); // здесь будет значение по умолчанию

Yup поддерживает не только разные тексты, но и разные локали, что актуально для многоязычных сайтов.

А что делать в ситуации, когда мы работаем с объектом, у которого каждое свойство имеет свои собственные проверки? Yup решает эту задачу очень элегантно, через рекурсивное определение:

// object().shape() позволяет задать структуру объекта
const schema = yup.object().shape({
  name: yup.string().required(),
  age: yup.number().required().positive().integer(),
  email: yup.string().email(),
  website: yup.string().url(),
  createdOn: yup.date().default(() => new Date()), // значение по умолчанию
});

const data = {
  name: 'jimmy',
  age: 24,
};
schema.validateSync(data);

https://repl.it/@hexlet/js-object-oriented-design-buider-yup-object#index.js

Но и это еще не все, yup позволяет добавлять дополнительные проверки, которые изначально в него не включены. Подробнее про эту возможность можно прочитать в документации.


Дополнительные материалы

  1. JSON schema

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 25 000 ₸ в месяц
Разработка фронтенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 28 ноября
профессия
от 39 525 ₸ в месяц
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
16 месяцев
с нуля
Старт 28 ноября
профессия
от 25 000 ₸ в месяц
Разработка бэкенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 28 ноября

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»