# 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
1год назад назад
Шикарно, благодарю.
monsterlessons
1год назад назад
Спасибо
Andrey Petko
1год назад назад
Хорошо бы еще добавить, для примера, механизм определения необходимой стратегии в зависимости от входящий параметров (действий пользователя). И там уже можно и про солид рассказывать.
monsterlessons
1год назад назад
Спасибо за идею. Добавил SOLID в список будущих видео.
Иван Древаль
1год назад назад
Познавательно ... Я так понимаю это один из вариантов реализации плагинов?
monsterlessons
1год назад назад
Именно так.
Galeups
1год назад назад
Спасибо большое, за простое и доступное объяснение.
monsterlessons
1год назад назад
На здоровье)