Поиск истины и красоты с помощью шаблонов проектирования программного обеспечения

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

Есть много причин, по которым добавление шаблонов проектирования в ваш арсенал ИТ-инструментов поможет вашему карьерному росту, но три наиболее важные из них:

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

Все продумано; мало что сделано хорошо!

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

ТВЕРДЫЕ принципы

Ранее мы видели, как принципы SOLID применяются к самой архитектуре, но здесь мы сосредоточимся на том, насколько они важны для разработки программного обеспечения. Мы только поиграем с ними (т.е. код не будет предоставлен), но это будет хорошей отправной точкой для каждого Архитектора, который хочет понять, к чему стремится их Команда Разработки.

Начнем с определения… Как говорит Дядя Боб: «Это не законы. Они не являются совершенными истинами. Это утверждения порядка: «Яблоко в день, чтобы доктора не было». Это означает, что они не являются чем-то вроде волшебства, которое ведет в Землю Обетованную молока, меда и отличного программного обеспечения, но, тем не менее, они вносят решающий вклад в создание надежного и долговечного программного обеспечения.

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

• Связывание — это то, как классы взаимодействуют друг с другом, а
• Сплоченность — как устроен отдельный класс.

SOLID означает следующие термины:

➊ —Принцип единой ответственности

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

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

➋ —Принцип открытого-закрытого

Вы должны иметь возможность расширять поведение класса, не изменяя его.

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

➌ —Принцип подстановки Лисков

Производные классы должны заменять свои базовые классы.

При расширении поведения класса A до подкласса B вы должны убедиться, что вы по-прежнему можете обменивать A на B, ничего не нарушая. Это может быть немного броским, особенно при сочетании этого принципа с принципом Open-Closed.

➍ —Принцип разделения интерфейса

Создавайте детализированные интерфейсы для конкретных клиентов.

Интерфейсы и классы должны быть максимально специализированными, чтобы вызовы клиентов не зависели от методов, которые они не используют. Это идет рука об руку с принципом единой ответственности.

➎ —Принцип инверсии зависимостей

Зависите от абстракций, а не от конкретики.

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

Шаблоны проектирования

Четыре автора (Gamma, Helm, Johnson & Vlissides) в 1994 году опубликовали (не)известную книгу Шаблоны проектирования: элементы многоразового объектно-ориентированного программного обеспечения, в которой были представлены 23 шаблона проектирования для объектно-ориентированного подхода. Из-за длинного названия ее стали называть Книгой Банды Четырех (GoF).

Начиная с определения:

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

Шаблоны проектирования не являются предписывающими и намеренно остаются высокоуровневыми. Они стремятся улучшить качество кода и в конечном итоге придерживаться принципов SOLID. Они также придерживаются этой рубрики: 1. Проектируйте интерфейсы, 2. Предпочитайте композицию наследованию и 3. Инкапсулируйте любую изменчивость.

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

  • Creational: они предоставляют механизмы создания объектов.
  • Структурный: они сосредоточены на объединении объектов в более крупные структуры.
  • Поведенческие. Они заботятся об эффективном общении и распределении обязанностей между объектами.

На следующей диаграмме показаны шаблоны GoF, которые мы собираемся изучить:

➊ — Строитель | творческий

Шаблон Builder предназначен для пошагового создания сложного объекта, а также для отделения построения от его представления. По сути, это позволяет создавать различные типы и представления объекта, используя один и тот же код.

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

➋ — Заводской метод | творческий

Фабричный метод определяет интерфейс для создания объектов, но создание экземпляров осуществляется подклассами.

— Показания к использованию: точные типы и зависимости объектов заранее неизвестны.

➌ — Абстрактная Фабрика | творческий

Абстрактная фабрика показывает, как создавать семейства связанных объектов без указания их конкретных классов.

— Указание для использования: существуют разные случаи, требующие различных реализаций наборов правил, которые либо неизвестны заранее, либо вызывают озабоченность по поводу расширяемости.
⭐️ Разница с абстрактным методом :
• Абстрактная фабрика: создает другие фабрики, а эти фабрики, в свою очередь, создают объекты, производные от базовых классов.
• Фабричный метод: создает объекты, производные от определенного базового класса.

➍ — Декоратор | Структурный

Шаблон Decorator динамически прикрепляет к объекту новые обязанности, помещая его в специальный класс-оболочку, который содержит эти поведения, поэтому сигнатура исходных методов не влияет (композиция вместо наследования).

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

➎ — Фасад | Структурный

Шаблон Facade предоставляет упрощенный интерфейс для библиотеки, API, фреймворка или любого другого сложного набора классов. Это фактически оболочка для сложной зависимой подсистемы.

— Индикация для использования: Отделение подсистемы от ее потенциальных клиентов путем инкапсуляции ее в единый интерфейсный объект, который становится единственной точкой доступа/шлюзом к этой системе.

➎½ — Репозиторий

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

— Показания к использованию: отделение бизнес-логики от кода доступа к данным.

Стратегия | Поведенческий

Шаблон Strategy определяет семейство алгоритмов, помещая каждый в отдельный класс и делая их взаимозаменяемыми. Инкапсуляция поведения в отдельные классы устраняет любые условные операторы, и правильный алгоритм (то есть стратегия) выбирается во время выполнения.

— Показания к использованию: существуют разные реализации бизнес-правил или необходимы разные варианты алгоритма.

➐ — Шаблонный метод | Поведенческий

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

— Показания к использованию. Существует согласованный набор шагов, которым нужно следовать, но отдельные шаги могут иметь разную реализацию.
⭐️ Разница со схемой стратегии:
• Шаблон: алгоритм выбирается на во время компиляции путем подкласса.
• Стратегия: алгоритм выбирается на во время выполнения с помощью сдерживания.

➑ — Цепочка ответственности | Поведенческий

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

— Индикация использования: запрос может обрабатываться более чем одним объектом, а обработчик (ни последовательность) заранее неизвестен.

➒ — Наблюдатель | Поведенческий

Шаблон Observer (также известный как Publish/Subscribe или PubSub для краткости) обеспечивает простую трансляцию связи, определяя зависимость "один ко многим" между объектами, так что, когда один объект подвергается изменению в состоянии, все его иждивенцы уведомляются и обновляются автоматически. Наблюдатель несет ответственность за регистрацию события, за которым он «наблюдает».

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

➓ — Команда | Поведенческий

Шаблон Command работает с запросами между двумя классами, превращая их в автономные объекты, которые инкапсулируют всю информацию о запросе, включая данные, аргументы метода, бизнес-логику и т. д.

— Указание для использования: необходимо выдавать запросы к объектам, не зная внутренностей запрашиваемой операции или получателя запроса.
⭐️ примечание Шаблон цепочки ответственности может использовать команды для представления запросов в виде объектов.

Сноска

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

Хороший дизайн очевиден. Отличный дизайн прозрачный.

Спасибо за прочтение!

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