Шаблоны GRASP: Polymorphism, Pure Fabrication, Indirection, Protected Variations

Привет, Хабр! Меня зовут Владислав Родин. В настоящее время я являюсь руководителем курса «Архитектор высоких нагрузок» в OTUS, а также преподаю на курсах, посвященных архитектуре ПО.

Специально к старту нового набора на курс «Архитектура и шаблоны проектирования» я продолжаю серию своих публикаций про шаблоны GRASP.


Введение

Описанные в книге Craig’а Larman’а «Applying UML and patterns, 3rd edition», GRASP’овские паттерны являются обобщением GoF’овских паттернов, а также непосредственным следствием принципов ООП. Они дополняют недостающую ступеньку в логической лестнице, которая позволяет получить GoF’овские паттерны из принципов ООП. Шаблоны GRASP являются скорее не паттернами проектирования (как GoF’овские), а фундаментальными принципами распределения ответственности между классами. Они, как показывает практика, не обладают особой популярностью, однако анализ спроектированных классов с использованием полного набора GRASP’овских паттернов является необходимым условием написания хорошего кода.

Полный список шаблонов GRASP состоит из 9 элементов:

  • Information Expert
  • Creator
  • Controller
  • Low Coupling
  • High Cohesion
  • Polymorphism

В прошлый раз мы обсудили паттерн Controller. Сегодня предлагаю рассмотреть оставшиеся паттерны из списка.

Polymorphism

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

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

Наличие в коде конструкции switch является нарушением данного принципа, switch’и подлежат рефакторингу.

Злоупотребление полиморфизмом приводит к переусложнению кода и в общем случае не приветствуется.

Pure Fabrication

Необходимо обеспечивать low coupling и high cohesion. Для этой цели может понадобиться синтезировать искуственную сущность. Паттерн Pure Fabrication говорит о том, что не стоит стесняться это сделать. В качестве примера можно рассматривать фасад к базе данных. Это чисто искуственный объект, не имеющий аналогов в предметной области. В общем случае любой фасад относится к Pure Fabrication (если это конечно не архитектурный фасад в соответствующим приложении).

Indirection

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

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

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

Protected Variations

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

На самом деле, это не паттерн, а цель, достигаемая соблюдением остальных паттернов.

Вывод

Шаблоны GRASP состоят из 8 паттернов:
1) Information Expert — информацию обрабатываем там, где она содержится.
2) Creator — создаем объекты там, где они нужны.
3) Controller — выносим логику многопоточности в отдельный класс или компонент.
4) Low Coupling 5) High Cohesion — проектируем классы с однородной бизнес-логикой и минимальным количеством связей между собой.
6) Polymorphism — различные варианты поведения системы при необходимости оформляем в виде полиморфных вызовов.
7) Pure Fabrication — не стесняемся создавать классы, не имеющие аналог в предметной области, если это необходимо для соблюдения Low Coupling и High Cohesion.
8) Indirection — любой класс вызываем через его интерфейс.
9) Protected Variations — применяя все вышесказанное, получаем устойчивый к изменениям код.

Читать ещё:

FavoriteLoadingДобавить в избранное
Posted in Без рубрики

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *