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

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

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

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

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

Fluent Interface

Текучий интерфейс (Fluent Interface) удобен для создания DSL. Domain Specific Language (Предметно-ориентированный язык) — язык, специализированный под конкретную область применения. Структура такого языка отражает специфику решаемых с его помощью задач. Яркий пример подобного языка — библиотека jQuery, с которой знакомо большинство программистов (или хотя бы слышали о ней).

// Вызов методов через точку в одной строчке
('#test').css('color', '#333').height(200);

На техническом уровне есть ровно два способа создать такой интерфейс.

This

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

class Collection
{
  constructor(coll) {
    this.coll = coll;
  }

  map(fn) {
    this.coll = this.coll.map((element) => fn(element));

    return this;
  }

  filter(fn) {
    this.coll = this.coll.filter((element) => fn(element));

    return this;
  }

  // Возвращает саму коллекцию, а не this.
  // Этот метод всегда последний в цепочке вызовов Collection.
  all() {
    return this.coll;
  }
}

const cars = new Collection([
  { model: 'rapid', year: 2016 },
  { model: 'rio', year: 2013 },
  { model: 'mondeo', year: 2011 },
  { model: 'octavia', year: 2014 },
]);

cars.filter((car) => car.year > 2013)
  .map((car) => car.model);
cars.all(); // [rapid, octavia]

У этого способа есть один серьёзный недостаток — объект изменяется. Это значит, что нельзя взять и просто так переиспользовать объект-коллекцию для разных выборок, потому что они начнут накладываться друг на друга.

На практике часто используется другой подход, с которым мы уже познакомились в прошлом курсе. Все, что нужно сделать — добавить немного функциональности в ооп, то есть возвращать не this, а создавать новый объект того же типа с обновлённой коллекцией.

class Collection {
  constructor(coll) {
    this.coll = coll;
  }

  map(fn) {
    const newColl = this.coll.map((element) => fn(element));

    return new Collection(newColl);
  }

  filter(fn) {
    const newColl = this.coll.filter((element) => fn(element));

    return new Collection(newColl);
  }

  // Возвращает саму коллекцию, а не this. Этот метод всегда последний в цепочке вызовов Coll.
  all() {
    return this.coll;
  }
}

const cars = new Collection([
  { model: 'rapid', year: 2016 },
  { model: 'rio', year: 2013 },
  { model: 'mondeo', year: 2011 },
  { model: 'octavia', year: 2014 },
]);

const filteredCars = cars.filter((car) => car.year > 2013);
const mappedCars = filteredCars.map((car) => car.model);
mappedCars.all(); // [rapid, octavia]
cars.all();
// [
//   { model: 'rapid', year: 2016 },
//   { model: 'rio', year: 2013 },
//   { model: 'mondeo', year: 2011 },
//   { model: 'octavia', year: 2014 },
// ]

Теперь каждый вызов возвращает новый объект. Такой код значительно безопаснее в использовании и позволяет без проблем переиспользовать новые коллекции. Изменение одной, не приведёт к автоматическому изменению всех остальных.


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

  1. Текучий интерфейс

<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 «Политикой конфиденциальности» и «Условиями оказания услуг».