PRINCIPIO DE SEGREGACIÓN DE INTERFACES EN PHP

El Principio de Segregación de Interfaces, Interface Segregation Principle, o ISP, es uno de los cinco principios SOLID de la programación orientada a objetos.
Fue propuesto por Robert C. Martin (Uncle Bob) y establece lo siguiente Los clientes no deberían verse obligados a depender de interfaces que no utilizan. En otras palabras: es mejor tener muchas interfaces pequeñas y específicas que una sola interfaz grande.

¿Por qué es importante este principio?

Cuando una interfaz contiene muchos métodos que no todos los programadores necesitan, se producen varios problemas:
  • Clases que implementan métodos vacíos o que lanzan excepciones (NotImplementedException).
  • Acoplamiento innecesario: un cambio en un método afecta a clases que no lo usan.
  • Dificultad para mantener y extender el código.
  • Violación del principio de responsabilidad única a nivel de interfaces.

Ejemplo en PHP

Se tiene un sistema que gestiona diferentes tipos de impresoras en una empresa.
  • Versión incorrecta:

    interface Impresora
    {
        public function imprimir(string $documento): void;
        public function escanear(string $documento): void;
        public function enviarFax(string $documento): void;
        public function fotocopiar(string $documento): void;
    }
    
    // Impresora básica que solo imprime
    class ImpresoraBasica implements Impresora
    {
        public function imprimir(string $documento): void
        {
       echo "Imprimiendo: $documento\n";
        }
    
        public function escanear(string $documento): void
        {
       throw new Exception("Esta impresora no puede escanear");
        }
    
        public function enviarFax(string $documento): void
        {
       throw new Exception("Esta impresora no tiene fax");
        }
    
        public function fotocopiar(string $documento): void
        {
       throw new Exception("Esta impresora no puede fotocopiar");
        }
    }
    
  • Problemas de diseño:
    • Se obliga a implentar métodos en la clase "ImpresoraBasica" que no se usan.
    • Si se agrega un nuevo método, por ejemplo "imprimirEnColor()", todas las impresoras, que implenten el interfaz "Impresora" deberán modificarse.
    • El código es frágil y difícil de mantener.
  • Versión correcta con Interfaces segregadas:

    // Interfaces pequeñas y específicas
    interface Imprimible
    {
        public function imprimir(string $documento): void;
    }
    
    interface Escaneable
    {
        public function escanear(string $documento): void;
    }
    
    interface Faxeable
    {
        public function enviarFax(string $documento): void;
    }
    
    interface Fotocopiable
    {
        public function fotocopiar(string $documento): void;
    }
    
    // Implementaciones según las capacidades reales
    class ImpresoraBasica implements Imprimible
    {
        public function imprimir(string $documento): void
        {
       echo "Impresora Básica - Imprimiendo: $documento\n";
        }
    }
    
    class ImpresoraMultifuncion implements Imprimible, Escaneable, Faxeable, Fotocopiable
    {
        public function imprimir(string $documento): void
        {
       echo "Multifunción - Imprimiendo: $documento\n";
        }
    
        public function escanear(string $documento): void
        {
       echo "Multifunción - Escaneando: $documento\n";
        }
    
        public function enviarFax(string $documento): void
        {
       echo "Multifunción - Enviando fax: $documento\n";
        }
    
        public function fotocopiar(string $documento): void
        {
       echo "Multifunción - Fotocopiando: $documento\n";
        }
    }
    
    Ahora se pueden usar las impresoras según sus capacidades reales:

    function procesarImpresion(Imprimible $impresora, string $doc)
    {
        $impresora->imprimir($doc);
    }
    
    // Solo acepta impresoras que puedan escanear
    function procesarEscaneo(Escaneable $escaneador, string $doc)
    {
        $escaneador->escanear($doc);
    }
    
    // Uso
    $basica = new ImpresoraBasica();
    $multifuncion = new ImpresoraMultifuncion();
    
    procesarImpresion($basica, "contrato.pdf");
    procesarEscaneo($multifuncion, "documento.jpg");
    

Beneficios del Principio de Segregación de Interfaces

Aplicar este principio eleva significativamente la calidad del código orientado a objetos en PHP.
  • Mayor flexibilidad: Puedes crear nuevas impresoras con solo las capacidades necesarias.
  • Mejor mantenibilidad: Cambios en una interfaz no afectan a clases que no la implementan.
  • Código más limpio y expresivo: Las clases declaran explícitamente qué capacidades tienen.
  • Facilita el testing: Es más fácil crear mocks y stubs de interfaces pequeñas.
  • Mejor adherencia a SOLID ya que complementa muy bien el Principio de Responsabilidad Única.

Consejos prácticos al aplicar Principio de Segregación de Interfaces en PHP

  • Revisar las interfaces con más de 3-5 métodos: probablemente se puedan segregar.
  • Usar interfaces de según lo que el cliente necesita en lugar de interfaces de implementación.
  • En proyectos grandes, combinar el principio de segregación de Interfaces con el uso de traits para reutilizar comportamientos.
  • En arquitecturas modernas, como DDD o Hexagonal, este principio ayuda a mantener los puertos (interfaces) muy enfocados.