# Strategy паттерн в Javascript

poster
В этом видео мы разберем такой паттерн, как Stategy, или по русски Стратегия. Он заключается в том, что у нас есть какая-то базовая сущность и мы хотим организовать код так, чтобы мы могли добавлять реализацию каких-то внутренних методов с помощью дополнительных сущностей.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

В этом видео мы разберем такой паттерн, как Stategy, или по русски Стратегия. Он заключается в том, что у нас есть какая-то базовая сущность и мы хотим организовать код так, чтобы мы могли добавлять реализацию каких-то внутренних методов с помощью дополнительных сущностей.

Один из примеров - это авторизация, которая обладает базовым функционалом и, которую мы можем с помощью дополнительный модулей расширять, делая, например, авторизацию по логину и паролю, либо по токену, либо через oath и так далее. Но главная идея в том, чтобы мы могли добавлять неограниченое количество модулей без изменения кода базовой сущности. Именно так работает passport.js в node.

Но давайте с вами сейчас попробуем этот паттерн на простом примере.

Мы хотим написать логгер, который в результате будет работать вот так.

logger(
  logToConsoleStrategy,
  'log',
  'log first message to console'
)

То есть мы передали в logger logToConsoleStrategy, которая будет реализовывать вывод в консоль, уровень лога: (log, error, warn) и сообщение.

Давайте реализуем этот код.

const logger = (strategy, level, message) => {
  return strategy(level, message)
}

const logToConsoleStrategy = (level, message) =>      console[level](message)

logger(
  logToConsoleStrategy,
  'log',
  'log first message to console'
)

Мы создали logger, который не содержит в себе никакого кода, но вызывает переданую стратегию с правильными аргументами.

И отдельно мы реализовали стратегию, которая может делать все, что угодно, но обязана быть функцией и иметь аргументы level и message.

Если мы посмотрим в браузер, то у нас вывелось сообщение к консоль.

Идея в том, что мы можем в любой момент заменить logToConsoleStrategy на любую другую стратегию и все будет по прежнему работать. Например, мы можем выводить ошибки на экран или отправлять в какой-то сервис ошибок с помощью fetch.

Давайте добавим стратегию вывода в DOM.

const logToDOMStrategy = (level, message, node) => {
  node.innerHTML = `<div class='${level}'>${message}</div>`
}

logger(
  logToDOMStrategy,
  'warn',
  'log second message to dom',
  document.querySelector('#log')
)

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

const logger = (strategy, level, message, ...args) => {
  return strategy(level, message, ...args)
}

И мы должны добавить элемент log в нашу разметку.

<div id='log'></div>

Если мы посмотрим в браузер, то у нас вывелось наше сообщение в DOM элемент и мы можем добавить стили для класса .warn.

<style>
  .warn {
    color: orange
  }
</style>

Таким образом мы можем легко добавлять новые стратегии не модифицируя на logger.

Паттерн стратегия позволяет легко масштабировать код добавляя стратегии и не изменяя базовую логику.

Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Sergey Illarionov
3 лет назад
Шикарно, благодарю.
monsterlessons
3 лет назад
Спасибо
Andrey Petko
3 лет назад
Хорошо бы еще добавить, для примера, механизм определения необходимой стратегии в зависимости от входящий параметров (действий пользователя). И там уже можно и про солид рассказывать.
monsterlessons
3 лет назад
Спасибо за идею. Добавил SOLID в список будущих видео.
Иван Древаль
3 лет назад
Познавательно ... Я так понимаю это один из вариантов реализации плагинов?
monsterlessons
3 лет назад
Именно так.
Galeups
3 лет назад
Спасибо большое, за простое и доступное объяснение.
monsterlessons
3 лет назад
На здоровье)