GRASP (Patrones de software de asignación de responsabilidad general) es un conjunto de nueve principios introducidos por Craig Larman en 'Aplicación de UML y patrones' (1997). Mientras SOLID le dice cómo estructurar las relaciones de clases individuales, GRASP aborda una pregunta más fundamental que todo desarrollador enfrenta en el momento del diseño: ¿qué objeto debería ser responsable de este comportamiento? GRASP proporciona heurísticas con nombre para responder esa pregunta de forma sistemática en lugar de por intuición. Los patrones no son algoritmos: son lentes que hacen que el proceso de razonamiento sea explícito y comunicable.
Information Expert es el patrón GRASP aplicado con más frecuencia y la fuente de la pregunta de diseño más común: "¿Dónde debería colocar este método?" La respuesta: en la clase que tiene los datos que necesita el método. Si calcular el total de un pedido requiere conocer los artículos en línea, la clase de Pedido (que contiene los artículos) debe calcular su propio total, no un servicio externo que llega al interior del Pedido para extraer los artículos.
El patrón Controlador responde: ¿quién debería manejar un evento del sistema (una acción del usuario, un mensaje entrante, un desencadenante programado)? No los objetos de dominio: deberían ignorar los mecanismos de entrega. No la interfaz de usuario: debería ignorar la lógica empresarial. El Controlador es una clase que no es UI y que recibe eventos y los delega en objetos de dominio. Coordina pero no calcula. En la práctica: un controlador REST es un controlador GRASP. También lo es un consumidor de mensajes, un controlador de comandos CLI o un programador de trabajos por lotes: todos son controladores para diferentes mecanismos de entrega.
El patrón Polimorfismo aborda la variación de comportamiento basada en tipos. Cuando ve un interruptor o if/else en un campo de tipo, generalmente es una señal de que se aplica el patrón de polimorfismo: cada rama del condicional debe ser un subtipo, y el comportamiento debe ser enviado por el sistema de tipos, no por la persona que llama. Esto está directamente relacionado con OCP: el switch crece con cada nuevo tipo; El polimorfismo significa agregar un nuevo tipo y agregar una nueva clase sin tocar el código existente.
Larman llamó a las variaciones protegidas "el principio más fundamental en el diseño de software", y es difícil argumentar lo contrario. Cada patrón de diseño, cada estilo arquitectónico, cada abstracción existe para proteger el código estable de cambios volátiles. La aplicación práctica: identifique los puntos de inestabilidad en su sistema (API externas, reglas comerciales que cambian con frecuencia, tecnología de bases de datos, bibliotecas de terceros) y envuelva cada uno en una interfaz estable. El código que depende de la interfaz está protegido: no cambiará cuando cambie la inestabilidad.
Pure Fabrication resuelve la tensión entre la alta cohesión y la necesidad de trasladar los problemas de infraestructura a alguna parte. Considere la persistencia: la entidad Orden no debe saber cómo guardarse en una base de datos; eso violaría el SRP e introduciría infraestructura en el dominio. Pero la lógica de la persistencia debe vivir en alguna parte. Un repositorio es una pura fabricación: una clase inventada con fines de diseño que no tiene una contraparte directa en el dominio del problema. Existe para darle al comportamiento de persistencia un hogar de alta cohesión y bajo acoplamiento. Otros ejemplos: Mapper, Logger, EventPublisher, CacheManager. Todas son puras fabricaciones, inventadas para el diseño, no para el dominio.