Казалось бы, простой вопрос: что такое паттерны проектирования?
ООП
,
В индустрии разработки ПО есть ряд тем, о которых ведутся споры почти в каждой компании. Я считаю, что история паттернов проектирования — одна из них. Можно найти сколько угодно постов, статей и ответов на Quora/Stackoverflow в пользу и не в пользу паттернов проектирования. Например, на днях я наткнулся на этот старый вопрос на Quora:
«Почему сейчас программисты меньше говорят о паттернах проектирования? Какие паттерны (если они есть) все еще представляют ценность?»
Автор имел в виду паттерны объектно-ориентированного проектирования или 23 паттерна, представленные в книге «Банды четырех», и большинство людей, отвечавших на вопрос, предположили, что так оно и есть. Однако «паттерн проектирования» — это термин, который зачастую приравнивается к«паттернам объектно-ориентированного проектирования» — так что не удивляйтесь, когда встретите странное заявление: «паттерны проектирования мертвы».
В этой статье мы собираемся ответить на, казалось бы, простой вопрос: что такое паттерн проектирования? Ответ на него поможет нам определить, о чем идет речь, когда мы обсуждаем или применяем тот или иной паттерн проектирования.
Что значат паттерны проектирования для вас?
Давайте отбросим все клише и сосредоточимся на том, что сразу приходит в голову, когда пытаешься концептуализировать паттерн проектирования. Это правило, которое нельзя нарушать? Это многословная академическая рекомендация? Это ещё одно ограничение проектирования? Или это информация, которую вам нужно знать только для того, чтобы пройти собеседование?
Для меня это как внутренний голос, подсказывающий: «не изобретай велосипед!». Возможно, вы испытывали желание начать процесс проектирования/сборки сразу после того, как вам была поставлена задача, и создали свое собственное решение — если так, добро пожаловать в клуб. Но в этом случае, если решение уже существует, разработка нового решения просто отнимает лишнее время и силы. Хотя желание сразу же приступить к разработке собственного решения может со временем притупиться, я считаю, что одним из важнейших инструментов, помогающих преодолеть это желание, является концепция паттерна проектирования.
Паттерны проектирования напоминают мне о том, что многие программисты уже сталкивались с той же задачей ранее и решили ее определенным образом по ряду причин. Вероятно, на то есть причины, и это дает нам возможность увидеть задачу в новом ракурсе, даже если мы не собираемся следовать этому паттерну.
Давайте обсудим абзац из первой главы к знаменитой книге GoF:
«Все мы знаем о ценности опыта. Сколько раз при проектировании вы испытывали дежавю, чувствуя, что уже когда-то решали такую же задачу, только никак не сообразить, когда и где? Если бы удалось вспомнить детали старой задачи и ее решения, то не пришлось бы придумывать все заново. Увы, у нас нет привычки записывать свой опыт на благо другим людям, да и себе тоже...»В большей или меньшей степени мы сталкивались с чем-то подобным: несколько раз решали общую задачу проектирования, когда не могли вспомнить уже имеющееся решение. Предоставляя возможности переиспользования способов решения повторяющихся задач, паттерны проектирования позволяют экономить время и усилия, которые можно направить на другие цели.
Теперь давайте подробно разберём некоторые фундаментальные понятия и определения.
Что понимается под паттернами?
Что такое паттерн? Концепция паттерна не является чем-то специфическим для нашей отрасли. Другие дисциплины и отрасли, такие как архитектура, экономика и т.д., также применяют эту концепцию. Давайте посмотрим на определение паттерна, данное Кристофером Александером, ведущим специалистом в области архитектуры:
«Каждый паттерн – это трехчастное правило, которое выражает связь между определенным контекстом, проблемой и решением.» (Alexander, 1979)
«Любой паттерн описывает задачу, которая снова и снова возникает в нашей работе, а также принцип ее решения, причем, таким образом, что это решение можно потом использовать миллион раз, и при этом никакие две реализации не будут полностью одинаковыми.» (Alexander, 1977)Теперь давайте посмотрим, что означают паттерны в индустрии разработки ПО:
«Архитектурный паттерн при разработке программного обеспечения описывает конкретную повторяющуюся проблему проектирования, возникающую в определенных практических ситуациях, и представляет хорошо проверенную общую схему ее решения. Схема решения определяется путем описания составляющих ее компонентов, их обязанностей и отношений, а также способов их взаимодействия.» (BMRSS, 96)Исходя из приведенных выше определений, мы можем рассматривать паттерн как трёхстороннюю взаимосвязь между ситуацией, проблемой и решением в сочетании с отношениями между ними. Однако это широкое понятие и может применяться в различных масштабах и на разных уровнях абстрагирования, от проектирования целой программной системы до решения задачи проектирования, относящейся к конкретному языку программирования.
Различные категории паттернов
Паттерны классифицируются в зависимости от их масштаба и уровня абстракции:
- Архитектурные паттерны
- Паттерны проектирования
- Идиомы
Архитектурные паттерны сосредоточены на структуре всей программной системы, ее подсистемах, различных широких компонентах и на том, как они сочетаются друг с другом. Эти паттерны находятся на высоком уровне абстракции. Например, не важно, какой язык программирования или какой фреймворк используется.
«Архитектурный паттерн выражает фундаментальную схему структурной организации программных систем. Он предоставляет набор предопределенных подсистем, определяет их обязанности и включает правила и рекомендации по организации отношений между ними.» (BMRSS, 96)С другой стороны, некоторые паттерны прослеживаются на самом низком уровне абстракции. Они называются идиомами и относятся как к проектированию, так и к реализации. Идиомы специфичны для конкретного языка программирования, то есть идиома в языке A не имеет значения в языке B.
«Идиома — это низкоуровневый паттерн, характерный для конкретного языка программирования. Идиома описывает, как реализовать определенные аспекты компонентов или отношений между ними, используя особенности данного языка.» (BMRSS, 96)Однако между вышеупомянутыми паттернами есть еще некоторые другие, касающиеся масштаба и уровня абстракции, и именно здесь принято говорить о паттернах проектирования.
Подробнее о паттернах проектирования
Итак, давайте рассмотрим определение оставшейся категории паттернов:
«Паттерн проектирования предоставляет схему для уточнения подсистем или компонентов программной системы, или отношений между ними. Он описывает часто повторяющуюся структуру взаимодействующих компонентов, которая решает общую проблему проектирования в определенном контексте.» (BMRSS, 96)Паттерны проектирования являются среднемасштабными, то есть они не являются ни высоко абстрактными, как архитектурные паттерны, ни привязанными к конкретным языкам программирования, как идиомы. Применение паттернов проектирования не влияет на структуру программной системы, но влияет на архитектуру подсистем и их более мелких компонентов.
Теперь давайте обсудим следующее утверждение (взятое из того же источника), содержащее важнейший факт о паттернах проектирования:
«Они, как правило, не зависят от конкретного языка программирования или парадигмы программирования.» (BMRSS, 96)В контексте той категорией паттернов, которая является предметом этой статьи, лучше перефразировать предыдущий тезис следующим образом:
«Они не зависят от конкретного языка программирования, но часто (могут) зависеть от парадигмы программирования.»Первая часть утверждения ясна: если паттерн зависит от конкретного языка программирования, то этот паттерн относится к категории идиом. Что касается второй части, то паттерны проектирования — это попытки решить общие проблемы, возникающие в парадигмах программирования. Скорее всего, они сформировались как ответ на недостатки парадигм. Например, в книге GoF описано 23 паттерна объектно-ориентированного проектирования, большинство из которых решают задачи, не представляющие проблем в парадигме функционального программирования. Но верно и обратное, поскольку паттерны проектирования зависят от контекста.
Как видно на следующем изображении, различные парадигмы могут иметь общие паттерны проектирования, но мы не будем затрагивать эту тему, поскольку она выходит за рамки данной статьи.
Анализ известного высказывания
Учитывая предыдущие разделы, давайте кратко рассмотрим утверждение, которое вы можете встретить, просто загуглив паттерны проектирования:
Функциональные языки не нуждаются в паттернах проектирования.
Вы можете найти пример здесь. Это утверждение неверно, поскольку подразумевает, что паттерны проектирования относятся только к объектно-ориентированной парадигме. Однако паттерны проектирования — это концепция, которая может присутствовать как в парадигме функционального программирования, так и в объектно-ориентированной парадигме. Просто паттерны проектирования могут быть специфичны для проблем и требований целевой парадигмы. Например, парадигма функционального программирования включает паттерны проектирования, специфичные для ее контекста.
Более того, как мы обсуждали в предыдущих разделах, разные парадигмы имеют разные контексты и, соответственно, сталкиваются с разными проблемами. Не стоит ожидать, что паттерны проектирования парадигмы B решат проблемы парадигмы A.
Краткое резюме
Паттерны проектирования, как и другие типы паттернов, призваны решить повторяющиеся проблемы, характерные для конкретного контекста.
- Они не зависят от языка программирования, но в основном связаны с парадигмой.
- Будучи среднемасштабными, они не столь абстрактны, как архитектурные паттерны.
- Их применение не влияет на фундаментальную архитектуру программной системы, но влияет на архитектуру подсистем.
- И последнее, но не менее важное: они (все типы паттернов) помогают нам не изобретать велосипед.
С моей точки зрения, паттерны проектирования не являются строгими законами, ограничивающими нашу свободу при проектировании. Они не догматичны и не безупречны, поскольку могут развиваться и становиться лучше или даже исчезать, но концепция паттернов проектирования все еще существует. Следование паттернам — это как образ мышления, который помогает нам понять, что у данной задачи может быть и более качественное решение.
P.S.
На сайте издательства продолжается весенняя распродажа.