Я действительно хочу объяснить шаблоны дизайна своими словами. Как сказал Альберт Эйнштейн:

Если вы не можете объяснить это просто, значит, вы недостаточно хорошо это понимаете. - Альберт Эйнштейн

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

Давайте посмотрим на этот шаблон проектирования под названием Стратегия.

Почему шаблоны проектирования?

Программная инженерия - сложная область, в которой много проблем. Эти архитектурные проблемы, вероятно, уже были кем-то решены, и есть руководство, которое мы называем «Шаблоны проектирования».

Дело в том, что не пытайтесь воссоздать уже существующее решение. Быть умным! Учитесь у предыдущих «поколений» и создавайте что-то лучшее, основываясь на предыдущих знаниях, для следующих поколений. Так будет развиваться программная инженерия.

Учитесь на предыдущих решениях, создавайте лучшие системы, оставьте большее наследие следующим инженерам-программистам.

Мы должны встать на плечи великана!

Эта проблема

Представим, что ваше приложение отвечает за обработку платежей. Цель обработки платежа довольно проста, мы должны взимать плату с клиента. Однако есть несколько способов сделать это, например:

  • Кредитная карта
  • Дебетовая карточка
  • Заготовка
  • Автоматическое списание средств с вашего банковского счета (например, GoCardless)
  • Биткойн
  • И так продолжается ...

Итак, у нас есть разные способы взимать плату с клиента. В этом случае у нас есть алгоритмы, которые делают одно и то же по-разному. В части кода они разные, но их цель одна - взимать плату с клиента.

Как мы можем это решить? Что ж, у нас может быть один простой класс, который будет обрабатывать платеж разными методами. Но это повлечет за собой множество обязанностей для одного и того же класса, который не соответствует принципу единой ответственности (SRP) или даже принципу открытого и закрытого типа (OCP), поскольку мы должны изменять класс платежей для каждого нового способа взимания платы с клиента.

Следовательно, как это элегантно решить?

Стратегия

Мы можем решить эту проблему с помощью шаблона разработки стратегии, который представляет собой шаблон проектирования поведения. Этот класс получит «стратегию» для достижения этой цели. Итак, это очень хорошо подходит для нашего примера. Мы хотим взимать плату с клиентов по-разному.

Чтобы применить шаблон стратегии, у нас будет:

  • Единый интерфейс, структурирующий способ работы стратегий
  • Один класс стратегии, который будет вызывать этот конкретный метод из данной стратегии
  • Несколько классов, чтобы делать одно и то же по-разному

Давайте углубимся в код TypeScript.

Типы и интерфейсы

Здесь мы собираемся определить структуру, которой должны следовать стратегии. Мы рассматриваем стратегию как класс, который будет делать то же самое по-разному. Итак, этот интерфейс будет контрактом между всеми стратегиями:

Здесь у нас есть тип платежа, а в интерфейсе есть только один единственный метод: charge (), который должен возвращать платеж.

Это просто! Давайте рассмотрим различные способы списания средств с клиентов и то, как они должны следовать этому интерфейсу.

Списание с дебетовой и кредитной карты

Здесь мы должны определить классы, которые будут делать одно и то же по-разному. То же самое: зарядить клиента. По-разному: один будет делать это с помощью кредитной карты, другой - с помощью дебетовой.

Они будут выглядеть так:

Каждый из них реализует интерфейс PaymentMethod, поэтому у них обоих должен быть метод charge (). Это дает много преимуществ:

  • У каждого класса есть свои собственные бизнес-правила, выполняющие одно и то же (разделение проблем).
  • У каждого класса своя ответственность (принцип единой ответственности).
  • Легко расширить. Если есть другой способ взимать плату с клиента, нам просто нужно создать новый класс, реализующий интерфейс PaymentMethod. Это полностью соответствует Open Closed Principe (OCP).

Как видите, это элегантный способ разделить обязанности. Однако как они будут работать? Вот почему мы увидим следующий класс: PaymentStrategy.

Платежная стратегия

Это будет класс, в котором мы сможем настроить стратегию, которую собираемся использовать в данный момент. У нас есть разные способы сделать одно и то же, но какой из них мы должны использовать? Стратегия это получает!

Итак, теперь мы полностью можем настроить стратегию, которую хотим использовать:

Что, если мы хотим использовать стратегию дебетовой карты? Это просто!

Заключение

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