Виммельбух, 3, перетяжка
Виммельбух, 3, перетяжка
Виммельбух, 3, перетяжка

Какие шаблоны проектирования стоит знать каждому программисту — отвечают эксперты

Аватар Никита Прияцелюк
Отредактировано

Нужно ли знать все шаблоны проектирования или сначала можно изучить несколько ключевых? И стоит ли вообще тратить время на их изучение? Узнаем у экспертов

28К открытий29К показов

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

Освоение шаблонов проектирования — это один из обязательных этапов в обучении начинающих разработчиков. Многие задачи, с которыми они сталкиваются, уже имеют типовые решения, которые помогают не только сэкономить время, но и избежать неочевидных ошибок. Кроме этого, знание шаблонов позволяет проще доносить свои идеи до команды и проще понимать существующие решения.

На мой взгляд, новичкам для начала надо разобраться с шаблонами Адаптер (Adapter), Декоратор (Decorator) и Заместитель (Proxy), т. к. они относительно простые для понимания, много где используются и позволяют понять подход. Эти шаблоны во многом схожи, но каждый решает разную задачу. Важно понимать их отличия.

После этого я бы рекомендовал изучить шаблоны Цепочка обязанностей (Chain of Responsibility), Наблюдатель (Observer), Стратегия (Strategy) и Спецификация (Specification), т. к. они описывают важные концепции, которые сейчас используются во многих фреймворках.

На самом деле паттернов проектирования не так уж и много, но в действительности некоторые из них используются реже других. Если очень грубо, то паттерны можно разделить на три части. Порождающие паттерны — они используются для проектирования новых объектов и коллекций объектов. Структурные — нужны для упорядочивания и унификации свойств различных объектов и классов. И поведенческие — описывают взаимодействие между объектами и сервисами. Я бы рекомендовал начать с порождающих паттернов и изучить их достаточно хорошо. Благо их не много, и они являются основой для остальных паттернов и архитектуры в целом. Старайтесь не только изучать паттерны, но и сразу применять их на практике. Иногда бывает полезно пересмотреть уже завершённые проекты с учётом новых знаний и перепроектировать их.

Шаблоны проектирования отличаются в разных экосистемах. Я рекомендую начать не с поиска универсальных, а с изучения принятых в вашей экосистеме. Например, фронтенд-разработчику, который использует React+Redux нужны одни шаблоны проектирования, а разработчику бэкенда на Go — совсем другие. Рекомендую начать с детального изучения своей экосистемы и принятых там подходов. Когда со своей экосистемой будет относительно понятно, то можно продолжить изучение подходов любой смежной области для расширения кругозора.

Кстати, классическая книга Design patterns 1994 ориентирована на задачи, актуальные для тогдашней разработки на C++. В 2019 году лучше поискать более свежие источники информации. Можно начать с поиска «technology_name best practices» — на первой странице будут не только рекламные тексты, но и 2–3 полезных результата.

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

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

В моей практике шаблоны, или паттерны проектирования, были и остаются скорее хорошей историей для собеседований — я встречал не так много людей, которые действительно ими мыслят и используют для решения задач. Тем не менее, знать основные и понимать разницу между их видами полезно.

Чаще всего в своей работе я встречаюсь с порождающими и структурными паттернами, такими как синглтон, фабрика, фабричный метод, фасад, адаптер. Первые два отвечают за контролируемое создание объектов, вторые — за связывание между собой различных компонентов или подсистем.

Что касается поведенческих паттернов, они, на мой взгляд, реже применяются. Дело в том, что правильная структура многих из них непроста, и, если прямо следовать предписанному проектированию, они могут чрезмерно усложнять структуру программы. Поэтому при использовании как этих паттернов, так и других, важно уметь видеть картину, происходящего целиком, и трезво оценивать целесообразность.

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

Разработчики же рассказывают, что на собеседованиях их зачастую настойчиво спрашивают про шаблоны GOF. На мой взгляд, знание конкретных шаблонов, в частности GOF, крайне переоценено в сообществе.

Есть вещи более важные, которые следовало бы знать каждому разработчику. Они гораздо сильнее влияют на эффективность и качество работы, чем знание конкретных примеров: «Фабрика», «Шаблонный метод» и т. д. Например, понимание, как работает операционная система, или что является узким местом в архитектуре современных компьютеров.

Конечно, изучать паттерны нужно, но я бы не стал выделять какой-то их конкретный набор. Советую обратить внимание в первую очередь на ваши рабочие задачи и изучать best practices по их решению. Например, если вы работаете с контейнерами, вам стоит познакомиться с Sidecar и Ambassador. Если работаете с UI, для вас будет полезно разобраться в словосочетании «конечный автомат» и познакомиться с MVC. Люди, работающие с инфраструктурой, могут почитать про Immutable server. Java-разработчики часто знакомы с Inversion of Control и Dependency Injection, но многим будет полезно знать и про Disruptor, Tolerant Reader, Event Sourcing.

Если же отвечать на поставленный вопрос кратко, то изучайте те шаблоны, которые помогают решать ваши ежедневные задачи более эффективным способом. Нет единого набора, который стоит знать каждому разработчику. Всё зависит от решаемых вами задач.

Большая часть сложных шаблонов, которые стали популярны в 90-х после выхода книги «Паттерны проектирования», сходит на нет. Сейчас все стремятся к простым решениям — пишут на JavaScript, Python и т. п. Там всё проще, в подобных языках без строгой поддержки типов сложные конструкции практически невозможно использовать. В целом, зубрить что-либо не стоит. Намного важнее иметь чувство кода. Если пишешь код и видишь, что что-то идёт не так, а ты сам не понимаешь, как сделать лучше, то можно обратиться к профессиональной литературе. Могу посоветовать книгу Стива Макконнелла «Совершенный код. Мастер-класс», например. Если хороший программист видит сложную ситуацию при проектировании, он её всё равно проработает вне зависимости от знаний конкретных шаблонов. Однако понимание шаблонов нужно для коммуникации. Современные программисты всё время общаются, что-то обсуждают. В этом общении есть свой жаргон, в котором присутствуют в том числе шаблоны. Это в основном довольно простые вещи: wrapper, singleton например. Нужно с ходу понимать, о чём идёт речь, чтобы эффективно коммуницировать с коллегами.

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

Ещё один важный момент, на который стоит обратить внимание — это постоянная актуализация своих знаний о шаблонах. Во многих сферах разработки они довольно часто меняются, и это нужно отслеживать, чтобы не натыкаться на устаревшие функции и элементы.

Существует, например, весьма известный шаблон проектирования интерфейса — MVC (Model View Control). Его часто применяют в разработке бизнес-приложений, он не привязан к конкретному языку программирования. Шаблон состоит из трёх компонентов: модель данных (Model), пользовательский интерфейс (View), управляющая логика (Control). Реализация каждого из компонентов делается отдельно, а их сочетание позволяет пользователю работать с данными через интерфейс. Такая модель реализации позволяет не только разделять работу по проектированию собственно интерфейса (View), управляющей логики (Control) и функциональной логики приложения (Model), но и создавать различные сочетания этих трёх компонентов.

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

Поясню: да, паттерны — объективная реальность разработки, однако «забивать» ими голову в самом начале своего пути в программировании пойдёт только во вред. Вместо того, чтобы доходить до базовых уровней понимания своей работы, новичок может заучить определённый паттерн и далее пытаться встраивать его в проект при любом удобном случае. Не вникать в суть вещей, а выискивать (подчас даже искусственно создавать) ситуацию, когда по его, новичка, мнению, было бы уместно использовать тот или иной паттерн.

То есть возникает ложный тотем в виде паттерна вместо реального обучения.

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

Но до тех пор гораздо полезнее обратиться с вопросом к старшему коллеге и получить от него реальное пояснение по вопросу, что называется, человеческим языком и из первых рук. Это в разы лучше для собственного развития, чем зубрить мёртвые схемы, не вытекающие из собственного опыта профессионального развития.

Мы делаем сайты на Битрикс, поэтому расскажу про PHP-программистов и frontend-программистов.

Чем больше шаблонов проектирования знает, а главное понимает, разработчик — тем лучше. Так что знать и понимать стоит всё. Чтобы не теряться, я предложил бы начать с изучения тех шаблонов, которые программист уже применяет, хотя даже не подозревает об этом.

Например, почти все веб-программисты так или иначе работали с библиотекой jQuery — а это уже целый набор шаблонов:

  • Компоновщик (Composite) — работа с множеством объектов как с одним объектом $('.button').hide();
  • Адаптер (Adapter) — работа со свойствами и событиями так, будто все браузеры одинаковые $(".container").css({opacity: .5});
  • Фасад (Facade) — создание более простых интерфейсов над сложными $.post() = $.ajax({type: "POST"});
  • Наблюдатель (Observer) — в принципе вся система событий в JS $(document).on('somethingHappened');
  • Итератор (Iterator) — перебор всех объектов $.each(...);
  • Заместитель (Proxy) — подмена одного объекта другим с аналогичным поведением. В jQuery — передача контекста this внутрь функции $("button").on("click", function () {$(this).addClass("active");}); внутри реализовано через $.proxy();
  • Строитель (Builder) — Создание нескольких объектов одной командой $('<li><a href="#">Link</a></ul>').

В Битрикс программист так же регулярно применяет несколько шаблонов:

  • Одиночка (Singleton) — это классы CMain и CDatabase;
  • Наблюдатель (Observer) — Система событий в Битрикс — класс EventManager (который ко всему ещё и Одиночка);
  • MVC — Модель-представление-контроллер — Компоненты 2.0 в Битрикс;
  • Адаптер (Adapter) — абстрагируемся от конкретной базы данных через класс CDatabase;
  • ORM — Работа с объектами вместо работы с базой напрямую;
  • Пространство имён (Namespace) — уменьшает кол-во глобальных переменных и предотвращает конфликты имён классов, функций и переменных.

У тех, кто пишет на React, тоже целый набор шаблонов:

  • Передача свойств вниз по дереву компонентов;
  • условный рендеринг;
  • деструктурирование свойств;
  • шаблон «провайдер»;
  • компоненты высшего порядка и т.д.

Есть очень хороший ресурс для начала изучения шаблонов проектирования. Тут 22 шаблона с иллюстрациями и примерами.

Для лучшего понимания шаблонов проектирования полезно освежить в голове принципы Объектно-ориентированного программирования (ООП), а также копнуть в сторону функционального программирования.

Итак, какие шаблоны проектирования нужно знать и действительно ли нужно?

Стоит помнить, что если вы новичок в программировании, то не стоит зацикливаться на шаблонах. Да, их полезно знать, но лучше сначала набраться опыта, чем прочитать про один-два шаблона и пытаться их всюду применить, не понимая сути.

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

Кроме того, для решения задачи знания подходящих шаблонов проектирования недостаточно. Не помешает изучить анти-шаблоны — подходы, которые приводят к плохим результатам.

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

И вообще, изучайте те шаблоны, которые будут помогать решать ваши ежедневные задачи.

Напоминаем, что вы можете задать свой вопрос экспертам, а мы соберём на него ответы, если он окажется интересным. Вопросы, которые уже задавались, можно найти в списке выпусков рубрики. Если вы хотите присоединиться к числу экспертов и прислать ответ от вашей компании или лично от вас, то пишите на experts@tproger.ru, мы расскажем, как это сделать.

Следите за новыми постами
Следите за новыми постами по любимым темам
28К открытий29К показов