← dev-notes
SOLID · 04 / 05

ISP
INTERFACE SEGREGATION

Ningún cliente debe depender de métodos que no usa

Interfaces mínimas Acoplamiento nominal Roles
01 Definición formal
FORMAL · DEFINICIÓN

Ningún cliente debe verse forzado a depender de métodos que no utiliza. Las interfaces deben ser cohesivas y pequeñas respecto a los roles que los consumidores requieren; una interfaz «gorda» acopla a todos los implementadores a preocupaciones ajenas.

El ISP es el hermano del SRP aplicado a contratos: muchas interfaces específicas suelen mejorar que una general que mezcla responsabilidades ortogonales.

02 Idea clave

Si obligas a un desarrollador de librería interna a implementar deployToProduction() porque comparte interfaz con el equipo de SRE, introduces métodos vacíos, UnsupportedOperationException o mentiras en el contrato. Mejor modelar roles separados: quien codea, quien revisa PRs, quien tiene guardia.

03 Cuando se rompe · Java

Una sola interfaz «empleado tech» mezcla implementación de features, revisión de código y guardia on-call.

ROMPE ISP — INTERFAZ GORDA
public interface TechEmployee {
    void implementFeature(String ticketId);
    void reviewPullRequest(String prUrl);
    void acknowledgePagerDutyAlert(String incidentId);
}

public final class JuniorDeveloper implements TechEmployee {
    @Override public void implementFeature(String ticketId) { /* … */ }

    @Override public void reviewPullRequest(String prUrl) {
        throw new UnsupportedOperationException("aún no reviso PRs");
    }

    @Override public void acknowledgePagerDutyAlert(String incidentId) {
        throw new UnsupportedOperationException("no estoy en on-call");
    }
}
04 Aplicación adecuada · Java

El mismo humano puede implementar varios roles; cada consumidor solo pide el rol que necesita.

RESPETA ISP — ROLES SEGREGADOS
public interface FeatureContributor {
    void implementFeature(String ticketId);
}

public interface CodeReviewer {
    void reviewPullRequest(String prUrl);
}

public interface OnCallResponder {
    void acknowledgeAlert(String incidentId);
}

public final class JuniorDeveloper implements FeatureContributor {
    @Override public void implementFeature(String ticketId) { /* … */ }
}

public final class StaffEngineer
        implements FeatureContributor, CodeReviewer, OnCallResponder {
    @Override public void implementFeature(String ticketId) { /* … */ }
    @Override public void reviewPullRequest(String prUrl) { /* … */ }
    @Override public void acknowledgeAlert(String incidentId) { /* … */ }
}

El servicio de asignación de revisiones depende solo de CodeReviewer; el orquestador de incidentes solo de OnCallResponder. Nadie arrastra métodos fantasma.

05 Relación con patrones
PUENTE SOLID ↔ GOF
  • Facade: ofrece una interfaz pequeña para un caso de uso sin exponer todos los detalles internos.
  • Adapter: adapta APIs externas grandes a interfaces mínimas que tu dominio sí necesita.
  • Evita sobreingeniería: no fragmentes interfaces por anticipación extrema; hazlo por consumidores reales.