GRASP – Breve Introdução e Referência Rápida

Esse é um assunto antigo, publicado em 1997 por Craig Larman em seu livro “Applying UML and Patterns”. Porém, é de grande relevância no contexto do desenvolvimento de software e, por isso, vale a pena relembrar. Por haver bastante material na internet a respeito do GRASP, vou tentar contribuir apenas com um resumo que serve tanto como referência rápida quanto breve introdução para quem ainda não conhece.

GRASP significa General Responsibility Assignment Software Patterns (ou Principles) e trata-se de um conjunto de nove princípios fundamentais em design orientado a objetos que estão relacionados com a atribuição de responsabilidades entre os elementos do software, tais como módulos, classes e métodos. Quando falamos de “responsabilidades”, nesse contexto, estamos nos referindo a distribuição das ações que serão realizadas pelos elementos do software.

O que os princípios do GRASP nos oferece é uma forma de distribuir essas responsabilidades da melhor maneira possível, visando a qualidade do código com relação a torná-lo mais legível, desacoplado e fácil de manter – tanto manutenção corretiva quanto evolutiva.

A seguir, serão apresentados de forma resumida os nove princípios do GRASP:

1. Information Expert oy Expert Principle: A melhor classe para assumir uma responsabilidade é aquela que possui todos os dados necessários para realizá-la. Se uma classe não possui todos os dados necessários, ela não pode realizar aquilo que precisa, logo, essa classe não é o melhor elemento para receber a responsabilidade.

2. Creator: Atribua a classe B a responsabilidade de criar uma classe A quando:

  • B contém ou agrega de forma composta A
  • B registra A
  • B usa de perto A
  • B tem os dados de inicialização para A

3. Controller: É o primeiro objeto, depois da camada de interface com o usuário, a receber e coordenar uma operação do sistema. O objeto deve receber essa responsabilidade quando se enquadrar nos cenários a seguir:

  • O objeto representa todo o sistema, a raiz do sistema, o dispositivo onde o software executa ou o subsistema.
  • O objeto representa um cenário de caso de uso onde a operação funciona.

4. Low Coupling: Ao atribuir uma responsabilidade, tenha certeza de estar reduzindo ao máximo a dependência com outros elementos do sistema. Quanto mais isolado e independente for o elemento, menos acoplado ele está. Essa medida reduz o impacto de mudanças e promove o reuso de componentes.

5. High Cohesion: Atribuir uma responsabilidade de modo que o elemento torne-se o mais focado, inteligível e fácil de manter possível. Quanto maior a coesão menor será o acoplamento.

6. Indirection: Consiste em criar um componente para servir como mediador (Mediator Pattern) entre dois ou mais componentes que estão relacionados. Essa medida evita o acoplamento direto entre esses componentes que precisam se relacionar.

7. Polymorphism: Quando um comportamento varia conforme o tipo do objeto (sua classe), atribua a responsabilidade ao método que representa tal comportamento. Dessa maneira, usando polimorfismo, podemos evitar sentenças condicionais no código para saber qual comportamento adotar. Esses comportamentos serão acionados de acordo com o tipo de cada objejeto.

8. Pure Fabrication: Quando os demais princípios não forem suficientes para atribuir uma responsabilidade sem causar baixa coesão e alto acoplamento, crie uma classe para assumir essa responsabilidade. Um exemplo desse princípio é o padrão Domain Service usado no DDD, ele contém a lógica que não pertence a uma entidade específica.

9. Protected Variations: Consiste em identificar pontos de variações e instabilidades nos elementos do sistema para criar uma interface estável em torno deles. Com essa medida, protegemos o resto do sistema das variações e da instabilidade desses elementos.

Se você for familiarizado com o assunto, esse resumo vai ajudar a lembrar de algumas coisas pontuais, quando necessárias. Mas se o assunto for novo para você, recomendo procurar outras fontes e continuar se aprofundando nele. Os ganhos pela aplicação desses princípios em projetos de software são significativos e aumentam a qualidade do produto final.