GRASP — General Responsibility Assignment Software Patterns
Nueve patrones para asignar responsabilidades a clases y objetos: Experto en Informacion, Creador, Controlador, Bajo Acoplamiento, Alta Cohesion y mas.
GRASP (General Responsibility Assignment Software Patterns) es un conjunto de nueve principios definidos por Craig Larman para guiar como asignar responsabilidades a clases y objetos en el diseno orientado a objetos:
- Experto en Informacion — asigna la responsabilidad a la clase que tiene la informacion necesaria para cumplirla.
- Creador — la clase B debe crear instancias de A si B contiene, agrega o registra objetos A.
- Controlador — un objeto no-UI coordina los casos de uso del sistema.
- Bajo Acoplamiento — minimiza las dependencias entre clases para facilitar el cambio.
- Alta Cohesion — cada clase tiene responsabilidades fuertemente relacionadas entre si.
- Polimorfismo — usa polimorfismo en lugar de condicionales para manejar variaciones de comportamiento.
- Indireccion — introduce un intermediario para desacoplar componentes.
- Fabricacion Pura — crea una clase artificial para mantener alta cohesion y bajo acoplamiento.
- Variaciones Protegidas — encapsula los puntos de variacion para que los cambios no se propaguen.
Ejemplo: Experto en Informacion
// Violation — OrderService knows too much about Order's internals
class OrderService {
calculateTotal(order) {
return order.items.reduce((sum, item) => sum + item.price * item.qty, 0);
}
calculateDiscount(order) {
const total = this.calculateTotal(order);
return total > 100 ? total * 0.1 : 0;
}
}
// Applying Information Expert
// Order owns the data, so it handles the calculations
class Order {
constructor(items) {
this.items = items;
}
getTotal() {
return this.items.reduce((sum, item) => sum + item.price * item.qty, 0);
}
getDiscount() {
return this.getTotal() > 100 ? this.getTotal() * 0.1 : 0;
}
getFinalPrice() {
return this.getTotal() - this.getDiscount();
}
}
const order = new Order([
{ price: 60, qty: 2 },
{ price: 10, qty: 1 },
]);
console.log(order.getFinalPrice()); // 117
Order concentra toda la logica sobre su propio estado. OrderService queda libre de conocer la estructura interna de los items.