Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос нашим менторам. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете
JS: Полиморфизм

Null Object Pattern

На сайтах, у которых есть аутентификация, внутри присутствует понятие "текущий пользователь". Это тот пользователь, который аутентифицировался через форму (или вошёл через социальную сеть). Текущий пользователь активно используется для вывода различных блоков информации, например, чтобы отобразить блок этого пользователя. Подобный код обычно выглядит так:

// где-то в воображаемом шаблоне articles/index.html.slim

if isAuthenticated && currentUser.hasArticles()
  each article in currentUser.getArticles()
    // тут выводим статьи

Обратите внимание на проверку существования пользователя. Если её не сделать, то код упадёт с ошибкой, потому что вызывается метод hasArticles() у null (так как пользователь отсутствует, если он не залогинился). Когда этих проверок одна-две, то ничего страшного, но если их много, то код быстро захламляется. Кроме того, такую проверку очень легко забыть вставить.

Можно ли решить эту задачу каким-то другим способом? Оказывается можно. Достаточно использовать полиморфизм подтипов. Для этого создаётся класс, описывающий пользователя, не прошедшего аутентификацию, например, Guest. Затем в него добавляются все необходимые методы, для которых мы хотим получить полиморфное поведение.

class Guest
{
  hasArticles() {
    return false;
  }

  getArticles() {
    return [];
  }
}

Большинство этих методов возвращает false либо пустые списки, так как у этого пользователя ничего нет. Зачем тогда он нужен? Всё очень просто: теперь клиентский код всегда рассчитывает на существование пользователя и ему больше не нужно проверять аутентификацию:

if currentUser.hasArticles()
  each article in currentUser.getArticles()
    // тут выводим статьи

Условные конструкции уйдут по всем шаблонам, но остаётся вопрос. А где и как происходит сам процесс создания нашего пользователя? И вот здесь останется тот единственный if, благодаря которому произойдёт создание правильного объекта. Это происходит на этапе обработки входящего запроса, и конкретное место зависит от используемого фреймворка. Код в этом месте выглядит примерно так:

const fetchCurrentUser = (req) => {
    const userId = req.session.userId;
    // Если id есть в сессии, то выбираем пользователя из базы, иначе возвращаем гостя
    return userId ? User.find(userId) : new Guest();
};

У такого способа использования полиморфизма есть особое название: шаблон проектирования "null object". Он часто используется внутри фреймворков и иногда встречается в прикладном коде. На Хекслете таких мест как минимум 3. Например, в классе Guest у нас десятки методов. Вот его содержимое (не полностью):

# Код на руби, но он прост как две копейки
class Guest
  def id
    nil
  end

  def avatar
    nil
  end

  def github_account
    false
  end

  def has_passed_at_least_one_project?
    false
  end

  def city
    ''
  end

  def seeking_job?
    true
  end

  def mentor?
    false
  end

  def locale?
    nil
  end

  def guest?
    true
  end

  def current_subscription_object
    FreeSubscription.new(self)
  end

  def type
    'guest'
  end

  def topics_count
    0
  end
end

<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

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

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

Для полного доступа к курсу нужна профессиональная подписка

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

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Зарегистрироваться

или войти в аккаунт

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

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».

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

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

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

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».