Pull to refresh

ООП для ООП: GRASP

Reading time 4 min
Views 62K
GRASP — General Responsibility Assignment Software Patterns (основные шаблоны распределения обязанностей в программном обеспечении)

Когда речь заходит о термине «ООП», все непременно подразумевают Объектно-Ориентированное Программирование, но сегодня речь пойдет не о нем. Почти. Сегодня я бы хотел рассказать о принципах Объектно-Ориентированного Проектирования, а в частности о шаблонах GRAPS и области их применения.

GRASP состоит из 9 шаблонов:
  • Creator
  • Controller
  • Pure Fabrication
  • Information Expert
  • High Cohesion
  • Indirection
  • Low Coupling
  • Polymorphism
  • Protected Variations

Но сегодня рассмотрены будут не все, а только основные. При этом хочу добавить что не все шаблоны являются «программными». Некоторые из них (например High Cohesion и Low Coupling) это принципы, а не примеры реализации.

Чем больше опыта за плечами у разработчика ПО, тем больше он осознает смысл предварительного проектирования и макетирования, и тем позже он приступает к непосредственной разработке системы, даже если это БД из четырех таблиц. Это в нем отзывается лень :) Ведь именно из-за того, что в нескольких предыдущих проектах проектированию уделили слишком мало времени, в итоге система переписывалась на 40-60%%, а среднестатистический мыслящий программист не любит делать одно и то же по многу раз, вот и «приходится» уделять больше времени на предварительный анализ. И именно тут его начинают интересовать такие аспекты разработки ПО как объектно-ориентированный анализ и проектирование.

Итак, поняв, что на моделирование необходимо уделить больше времени, актуальным становится следующий вопрос: «НУ а что ж такого тут проектировать, если и так все понятно?» Вобщем-то, если за плечами довольно большой груз знаний и опыта, а с ООА/П сталкиваться не приходилось, то все решения принимаются на уровне интуиции, а чтение литературы приводит только к систематизации знаний и, возможно, новым подходам. Так, со временем, для себя открывают GRASP.

Как было сказано ранее, GRASP — это шаблоны проектирования. А именно — шаблоны, которые отвечают за взаимосвязь объектов в системе. Сколько раз вы задумывались над тем, где будет порождаться новый объект? В данном материале я хочу рассмотреть основные шаблоны GRAS ( «P» опускаю для избежания тавтологии, так как в аббревиатуре оно заменяется ловом «шаблоны»), на примере блога.

Creator.


Как часто вам приходилось задумываться о том, кто должен создавать объект X? Часто приходят к выводу, что объект должен создаваться независимо от кого-то, часто эту задачу возлагают на хранилище объектов (класс-коллекцию), а иногда на иные объекты системы. Что же правильно и какой вариант выбрать?
Шаблон creator говорит нам какие условия должны соблюстись, что бы объекты верно порождали друг друга. Для этого есть несколько правил:
объект А должен порождать объект Б, если:
  • объект А содержит или агрегирует объекты Б (содержит в себе как свойство или коллекцию)
  • объект А активно использует объекты Б (основной объем работы с объектом Б происходит посредством объекта А)
  • объект А обладает данными инициализации объекта Б (каждый раз при создании объекта Б, данные берутся из объекта А)




Итак, взглянув на диаграмму отношений, на основании шаблона Creator можно сделать вывод, что экземпляры класса Post должны создаваться внутри класса Blog, а Comment — в Post. Почему так а не иначе? Например, почему Comment не должны создаваться в Blog? Ну хотя бы потому, что именно Post содержит в себе экземпляры Comment, а так же Post обладает информацией для создания экземпляра Comment (в нашем случае это всего лишь указатель на родителя, но даже этим не обладает Blog по отношению к Comment).

Information Expert


Информационный эксперт, как следует из названия, занимается не чем иным, как предоставлением информации об объекте. В нашем случае Information Expert должен отвечать на такие вопросы:
  • Кто должен знать кол-во комментариев к посту?
  • Кто должен знать общее кол-во комментариев в блоге?

Пытаясь ответить на эти вопросы, нам необходимо определить, кто из участников системы имеет необходимые сведения. Так getCommentsCount() стоит назначить объекту Post, а объект Blog, на основании промежуточных значений каждого из входящего в него объекта Post получит общую сумму комментариев getTotalComments().



Но при этом именно Post должен отвечать за такие аспекты, как «получить название поста» ( getTitle() ), «получить пост», «получить автора» и пр.

Controller


Ну тут все просто. Это не что иное, как C из аббревиатуры MVC :) Этот шаблон отвечает за то, к кому именно должны обращаться вызовы из V (View), и кому C должен делегировать запросы на выполнение ( какая модель M должна их обработать )

Low Coupling


Низкая связанность, отвечает за то, что бы объекты в системе знали друг о друге как можно меньше. Ведь чем меньше объект знает о других объектах, тем больше будет изолировано и тем меньше правок необходимо будет делать, если в системе что-то поменяется.
На наших диаграммах все хорошо. Blog ничего не знает о Comment, а степени связанности у каждого класса составляют всего лишь единицу. В более сложных системах связей бывает гораздо больше, и шаблон Low Coupling позволяет избежать следующих проблем:
  • При изменении в связанных классах, необходимо делать локальные изменения в данном классе
  • Понимание каждого класса в отдельности усложняется и требует изучения всех связанных классов
  • Повторное использование становится невозможным из-за того, что перетянув часть системы, необходимо тянуть почти всю систему.


High Cohesion


Высокая степень зацепления — так переводится название шаблона. Это противовес предыдущего шаблона. Зацепление — процесс взаимодействия класса с другими классами системы и область ответственности за действия. Рассмотрим две диаграммы:





Как по вашему, что более правильно? Отвечая на этот вопрос с точки зрения Low Coupling, то первое, но так ли хорошо, когда один класс отвечает и за измерение температуры за окном и за движение метро и за расчет pi до 87342 знака после запятой? Именно поэтому High Cohesion твердит, что класс должен стараться выполнять как можно меньше не специфичных для него задач, и иметь вполне определенную область применения. Только с опытом приходит понимание балансировки между этими двумя шаблонами.

Все. На первое время достаточно :) Если статья будет иметь успех — обещаю рассказать о некоторых других шаблонах GRASP, а так же о шаблонах GoF и многом другом из мира ООА/ООП.

оригинал статьи в моем блоге
Tags:
Hubs:
+61
Comments 42
Comments Comments 42

Articles