Los principios DRY, KISS y YAGNI comparten propósito con los principios SOLID: guiar el diseño hacia soluciones mantenibles, comprensibles y evolutivas. En proyectos con Java, combinarlos permite sostener arquitecturas limpias sin caer en sobreingeniería.
Este capítulo explica cómo se conectan, qué tensiones surgen y cómo resolverlas mediante ejemplos concretos.
Partimos de un servicio que viola SRP y Liskov Substitution (LSP) al mezclar múltiples tipos de notificación con condicionales.
// Implementación inicial: mezcla de responsabilidades y futuros escenarios
class AlertService {
private final EmailClient emailClient;
private final SmsClient smsClient;
AlertService(EmailClient emailClient, SmsClient smsClient) {
this.emailClient = emailClient;
this.smsClient = smsClient;
}
void send(Alert alert) {
if ("EMAIL".equals(alert.type())) {
emailClient.send(alert.recipient(), alert.message());
} else if ("SMS".equals(alert.type())) {
smsClient.send(alert.recipient(), alert.message());
} else if ("PUSH".equals(alert.type())) {
// Futuro: push notifications
}
}
}
La refactorización aplica SRP, LSP y DIP (SOLID) junto con DRY/KISS/YAGNI: se extrae una jerarquía mínima de notifiers, se elimina el canal especulativo y el servicio queda simple.
// Implementación refactorizada: SOLID + DRY, KISS, YAGNI trabajando juntos
interface Notifier {
void send(Alert alert);
}
final class EmailNotifier implements Notifier {
private final EmailClient emailClient;
EmailNotifier(EmailClient emailClient) {
this.emailClient = emailClient;
}
@Override
public void send(Alert alert) {
emailClient.send(alert.recipient(), alert.message());
}
}
final class SmsNotifier implements Notifier {
private final SmsClient smsClient;
SmsNotifier(SmsClient smsClient) {
this.smsClient = smsClient;
}
@Override
public void send(Alert alert) {
smsClient.send(alert.recipient(), alert.message());
}
}
final class AlertService {
private final List<Notifier> notifiers;
AlertService(List<Notifier> notifiers) {
this.notifiers = List.copyOf(notifiers);
}
void send(Alert alert) {
notifiers.forEach(notifier -> notifier.send(alert));
}
}
Los canales existentes están modelados con clases concretas (SRP), nuevas variantes se agregan sin modificar el servicio (OCP), no hay duplicación de lógica (DRY), el flujo es simple (KISS) y no se implementaron canales hipotéticos (YAGNI).
Equilibrar DRY, KISS y YAGNI con SOLID mantiene sistemas flexibles y con un diseño progresivo. Cada principio ofrece una perspectiva distinta, y juntos permiten construir software sostenible en el tiempo.