Паттерны проектирования
Валентин Троян - автор блога WEB PADAWANВсем привет, юные падаваны! Сегодня я решил запустить первую рубрику на своём Telegram-блоге, под названием «Изучаем паттерны проектирования», или же сокращенно «Изучаем ПП». С чего это я вдруг решил заинтересоваться такой непростой темой? Причины, как всегда, есть две. Первая, это указано обязательным пунктом в программе по моей специальности в университете. Вторая, это может стать неплохим плюсом в дальнейшей карьере(и в поиске этой самой карьеры). В любом случае, с ними придётся столкнутся. И чем раньше – тем лучше. Поэтому, я начну с пилотной статьи, а там уже – как получится. Для начала, давайте узнаем, что же это вообще такое. Какие они бывают и зачем они в принципе нам нужны. Ну что же – приступим :)
Паттерн/шаблон проектирования (Design Pattern)
Для начала, давайте вообще разберёмся с тем, что же такое шаблон. Шаблон (паттерн) – это повторяющийся элемент в различных сферах жизни. Будь то дизайн, архитектура, сама природа. Им может быть всё что угодно. Например: та же снежинка(она имеет красивую шестилучевую симметрию, из-за чего каждая снежинка уникальна, но один и тот же паттерн повторяется на всех шести её лучах), плитка (как пример использования паттернов в дизайне помещений), окрас зебры.
Хоть каждая задача и программа уникальна, у них всё же есть какие-то общие черты. Разработчики их заметили и выделили те, которые чаще всего встречаются, в паттерны (шаблоны проектирования/программирования). В паттернах предлагается в том числе наиболее оптимальные способы реализации той или иной задачи.
Можно сказать, что шаблоны/паттерны проектирования (с английского – Design Patterns) – это типичные способы решения часто возникающих задач в сфере разработки ПО.
Стоит отметить, что шаблоны проектирования — это руководства по решению повторяющихся проблем. Это не классы, пакеты или библиотеки, которые можно было бы подключить к нашему приложению и сидеть в ожидании чуда.
Отличие паттернов от алгоритмов
Паттерны часто путают с алгоритмами (и я не исключение), ведь оба понятия описывают типовые решения каких-то известных проблем. Но если алгоритм — это чёткий набор действий, то паттерн — это высокоуровневое описание решения, реализация которого может отличаться в двух разных программах.
Давайте через аналогии, так будет немного понятнее. Алгоритм — это кулинарный рецепт с чёткими шагами, а паттерн — инженерный чертёж, на котором нарисовано решение, но не конкретные шаги его реализации. На рисунке снизу это видно более наглядно: слева - это алгоритм (рецепт пиццы), справа - паттерн (чертёж).
А нужны ли мне эти паттерны вообще?
Вполне вероятно, что мы некоторые из паттернов использовали в своих программах, в разработке сайтов, приложений и даже не подозревали об этом. Кстати, определить кто является профи в своём деле, а кто - пока ещё аматором, как раз возможно благодаря знанию этих шаблонов. Ведь нарезать колбасу можно и ножом, и ножницами, если хорошо так постараться. Только в отличии от аматора, профессионал знает, что ключевая фишка ножниц заключается немного в другом(и применять их лучше в другом случае). Так зачем же они нам?
· Стандартизация кода. Мы делаем меньше просчётов при проектировании, используя типовые унифицированные решения. Соответственно, все скрытые проблемы и подводные камни в них уже давно найдены и известны.
· Понимание с другими разработчиками. Мы можем часами рассказывать о том, какой крутой дизайн у нас появился в голове, какие нужны классы для его реализации и прочее. А можем, просто сказать два слова : "Паттерн ... (тут пишется название шаблона)" - и все тут же понимают, о чём речь.
· Проверенные решения. Зачем строить заново велосипед, если можно воспользоваться готовой машиной? Вот именно, незачем. Благодаря этим шаблонам, используя готовые решение, мы тратим меньше времени, и не создаем велосипед по новой. А как известно: время - деньги.
С бочкой мёда ясно, а что насчёт ложки дёгтя?
Разумеется, там где есть плюсы, обязательно должны быть и минусы. Идеального ничего не существуют, как бы сейчас не обижались все перфекционисты.
Применяй всегда и везде. Такая проблема возникает у новичков, которые только-только познакомились с паттернами(надеюсь, со мной такого не случится). Вникнув в паттерны, человек пытается применить свои знания везде. Даже там, где можно было бы обойтись кодом попроще.
Неэффективность решения. Паттерны пытаются стандартизировать подходы, которые и так уже широко используются. Для некоторых людей, эта стандартизация может показаться единственной истинной, или правильнее сказать - догмой. Благодаря чему, они реализуют паттерны, так сказать - «как в книжке». При этом, забывая приспособить их к реалиям проекта.
Костыли для слабого языка программирования. Нужда в паттернах появляется тогда, когда люди выбирают для своего проекта язык программирования с недостаточным уровнем абстракции. В этом случае, паттерны — это костыль, который придаёт этому языку суперспособности.
Группы шаблонов проектирования
Вообще, паттернов существует огромное множество, но в основном выделяют 23 классических шаблона проектирования. Это как с библиотеками/фреймворками в JavaScript. Почти каждый месяц – что-то новое выходит. Но основными игроками всё равно остаются эти 4 ребят: Angular, React, Vue, jQuery (хоть последний стараются использовать всё реже, всё же – он имеет место быть). То же самое и тут. Правда так как этих шаблонов много (23 – немаленькое количество!), то их решили объединить в три группы: Порождающие (Creational Design Patterns), Структурные (Structural Design Patterns), Поведенческие (Behavioral Design Patterns). Теперь о каждой группе отдельно.
Порождающие (Creational Design Patterns)
Эти шаблоны что-то создают. Этот тип особенно важен, когда система зависит не столько от наследования классов, сколько от композиции. Порождающие паттерны отвечают за создание объектов и позволяют системе быть независимой от типов этих самых объектов и от процесса порождения. Например, "как создать объект, который нельзя изменить"? "Как создать класс, который будет создавать новые объекты других классов?" и т.д.
Существуют следующие порождающие шаблоны:
· Простая фабрика (Simple Factory);
· Фабричный метод (Factory Method);
· Абстрактная фабрика (Abstract Factory);
· Строитель (Builder);
· Прототип (Prototype);
· Одиночка (Singleton).
Структурные (Structural Design Patterns)
Как говорит всеми великая Википедия: «Структурные шаблоны — шаблоны проектирования, в которых рассматривается вопрос о том, как из классов и объектов образуются более крупные структуры».
Если чуть перефразировать, то структурные шаблоны в основном связаны с композицией объектов, то есть с тем, как сущности могут использовать друг друга. Ещё одним объяснением было бы то, что они помогают ответить на вопросы: «Как создать программный компонент?» или «как заставить объекты с несовместимыми интерфейсами работать вместе?».
Список структурных шаблонов проектирования:
· Адаптер (Adapter);
· Мост (Bridge);
· Компоновщик (Composite);
· Декоратор (Decorator);
· Фасад (Facade);
· Приспособленец (Flyweight);
· Заместитель (Proxy).
Поведенческие (Behavioral Design Patterns)
Поведенческие шаблоны — шаблоны проектирования, определяющие алгоритмы и способы реализации взаимодействия различных объектов и классов. То есть, помогает добиться нужного поведения от объектов. Поведенческие шаблоны связаны с распределением обязанностей между объектами. Их отличие от структурных шаблонов заключается в том, что они не просто описывают структуру, но также описывают шаблоны для передачи сообщений / связи между ними. Они помогают ответить на такие вопросы: «Как запустить поведение в программном компоненте?», «как сделать так, чтобы объекты одного класса следили за изменениями в других классах и реагировали на них».
Поведенческие шаблоны:
· Цепочка обязанностей (Chain of Responsibility);
· Команда (Command);
· Итератор (Iterator);
· Посредник (Mediator);
· Хранитель (Memento);
· Наблюдатель (Observer);
· Посетитель (Visitor);
· Стратегия (Strategy);
· Состояние (State);
· Шаблонный метод (Template Method).
В итоге
Как можете заметить, паттерны проектирования имеют свои достоинства и недостатки. И если пока не применять их, то знать о существовании таковых, всё же стоит. Однако этих шаблонов, оказалось, не так уж и мало. Будет ли о каждом из них статья? Могу сказать точно, что паттерны, которые я буду изучать в университете, вот про них - у меня точно будет материал (+ с примерами кода). Сразу скажу, что я не профи, я только учусь. Так что, если я что-то упустил или нужно было о чём-то написать, а в статье этого нету - напишите мне, посмотрю что можно будет сделать.