Обучать других концепциям, которые вы узнали, — это лучший способ убедиться, что вы полностью их поняли.
Основываясь на предыдущем утверждении, я решил, что пришло время подтвердить то, что я узнал из шаблонов проектирования «Head First Design». ', резюмируя каждую главу в отдельной статье.

Эта статья о первой главе. который называется «Введение в шаблоны проектирования»
Здесь, в первой главе, автор хочет, чтобы вы почувствовали, что именно необходимо для шаблонов проектирования на реальном примере.
Итак, глава начинается с примера приложения SimUDuck. Это успешная игра с отсутствием уток. В игре можно показать большое разнообразие типов уток, которые плавают и издают крякающие звуки. Первоначальные разработчики системы использовали стандартные методы объектно-ориентированного программирования и создали один суперкласс Duck, от которого наследуются все остальные типы уток.

На данный момент все было замечательно, пока компания не решила расширить приложение и добавить в него еще одну величественную функцию.
И эта функция заключалась в том, чтобы добавить в приложение летающих уток.
Прямое мышление простым путем приводит к просто добавьте функцию fly() в суперкласс Duck, обратите внимание, что все подклассы наследуются от суперкласса Duck, тогда это приведет к тому, что все типы уток будут летать перед нами !!!!!! слишком плохой результат.

Кроме того, решение сделать функцию fly() здесь абстрактной функцией, а затем переопределить ее, чтобы ничего не делать с типами уток, которые не летают, приведет к постоянному переопределению каждого нового подкласса Duck, который когда-либо добавлялся в программу.

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

Потому что всякий раз, когда вам нужно изменить поведение, вы вынуждены следовать и изменять его во всех различных подклассах, где это поведение определено, возможно, добавляя новые ошибки по пути!

В этот момент вы, возможно, ждете шаблона проектирования, который придет и спасет вас. Здесь мы представим наш первый принцип проектирования.

' Речь идет о том, чтобы взять изменяющиеся части и инкапсулировать их, чтобы позже можно было изменять или расширять изменяющиеся части, не затрагивая те, которые не изменяются.
Итак, мы отделим поведение мухи от класса Duck.
И здесь мы изучим один из самых важных принципов проектирования
».

имейте в виду, что здесь под интерфейсом мы подразумеваем не точно конструкцию интерфейса Java, а подразумеваем класс супертипа.
Суть в том, чтобы использовать полиморфизм при программировании к супертипу, чтобы фактический объект среды выполнения не был заблокирован в коде. И мы могли бы выразить другими словами «программа для супертипа», поскольку «объявленный тип переменных должен быть супертипом, обычно абстрактным классом или интерфейсом, так что объекты, назначенные этим переменным, могут быть любой конкретной реализацией супертип, что означает, что класс, объявляющий их, не должен знать о фактических типах объектов!».

В соответствии с этой диаграммой в нашем классе Duck мы инициируем экземпляры QuackBehavior и FlyBehavior,
И у нас будет performQuack и performFly, и мы делегируем их классу поведения.
И для любого нового типа утки мы инициируем тип поведения полета и кряканья в конструкторе или с помощью функции set для установки тип поведения.

Знайте, когда в будущем нам понадобится добавить какое-либо новое поведение полета. Предположим, что «летать с вертолетом» мы просто создаем новый класс класса FlyWithHelicopter, который реализует интерфейс FlyBehavior и переопределяет fly(), и всякий раз, когда мы хотим изменить эту новую функцию поведения полета, мы просто переходим к классу класса FlyWithHelicopter и модифицируем функцию fly.
В этой вводной главе и после того, как мы углубимся в это приложение Duck, мы, наконец, представим шаблон стратегии.

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

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

https://maiajamdev.medium.com/head-first-design-pattern-summarize-chapter-2-observer-pattern-f0b6f2734133

*Два предыдущих рисунка взяты из книги.