Los anti-patrones son soluciones aparentemente convenientes que terminan generando problemas a largo plazo. En este capítulo revisamos conductas muy comunes que violan los principios SOLID, con ejemplos en Java y recomendaciones para darles la vuelta.
Un “objeto dios” centraliza múltiples responsabilidades: reglas de negocio, acceso a datos, validaciones y control de flujo.
class SistemaService {
void procesar(Pedido pedido) {
validar(pedido);
guardar(pedido);
enviarEmail(pedido);
generarReporte(pedido);
}
// docenas de métodos privados...
}
Cuando agregar una funcionalidad obliga a modificar múltiples archivos no relacionados hablamos de “cirugía de escopeta”. A menudo se debe a la falta de un punto único de extensión.
Es habitual ver estructuras switch
o cadenas de if
que revisan tipos o constantes para decidir el comportamiento.
class CalculadoraBonos {
BigDecimal calcular(String categoria, BigDecimal salario) {
switch (categoria) {
case "A": return salario.multiply(new BigDecimal("0.1"));
case "B": return salario.multiply(new BigDecimal("0.15"));
case "C": return salario.multiply(new BigDecimal("0.2"));
default: return BigDecimal.ZERO;
}
}
}
El código que pregunta constantemente por la clase concreta de un objeto indica que la jerarquía no respeta LSP.
void procesar(Notificacion notificacion) {
if (notificacion instanceof NotificacionEmail) {
enviarEmail((NotificacionEmail) notificacion);
} else if (notificacion instanceof NotificacionSms) {
enviarSms((NotificacionSms) notificacion);
} else {
throw new IllegalArgumentException("Tipo no soportado");
}
}
Una interfaz que agrupa operaciones ajenas entre sí obliga a los implementadores a depender de métodos que no necesitan.
interface ServicioGeneral {
void crear();
void actualizar();
void imprimir();
void exportar();
}
Ocurre cuando se crean dependencias concretas dentro de clases de alto nivel, impidiendo la inversión real.
class ReporteDomainService {
void generar() {
ExportadorPdf exportador = new ExportadorPdf();
exportador.exportar();
}
}
Exportador
) e inyectar la implementación por constructor o contenedor IoC.Este anti-patrón describe un sistema sin estructura reconocible. La falta de límites y contratos claros dificulta la aplicación de cualquier principio SOLID.
El “flujo de lava” son fragmentos de código legacy que permanecen por miedo a tocarlos. Muchos incumplen SOLID, pero nadie se anima a refactorizarlos.
Modificar tres o cuatro lugares al azar para “ver si se arregla” indica falta de comprensión del diseño. Suele ocurrir cuando las dependencias no están invertidas o las interfaces son confusas.
Detectar estos anti-patrones tempranamente permite aplicar SOLID antes de que el sistema se vuelva incontrolable. En el próximo tema exploraremos herramientas y técnicas para detectar incumplimientos de los principios de forma automatizada.