SOLID: Principio de segregación de interfaz o Interface segregation principle

En este artículo hablamos del cuarto principio de los principios de programación SOLID.

Significado

Este principio establece que las clases clientes de otras no deberían verse forzados a depender de interfaces que no usan. En su lugar se apoya la definición de interfaces más específicas para cada caso.

Cuando hablamos de interfaces estamos hablando del concepto de interfaz de clase del lenguaje de programación Java así como la adaptación a cualquier otro tipo de lenguaje de programación. Por ejemplo en Swift estaríamos hablando de protocolos.

En pocas palabras una interface es un acuerdo entre las clases que implementan la interfaz y la propia interfaz definida con sus propiedades y funciones. El acuerdo consiste en que cada clase que implemente dicha interfaz deberá codificar cada una de las propiedades y funciones definidas en la interfaz.

Ejemplo

Este principio es más sencillo de entender con un ejemplo.

Imaginemos que estamos modelando una interfaz de acciones para distintas clases de aves.

 

interface Ave {

    funcion comer()

    funcion cantar()

    funcion volar()

}

 

class Loro implements Ave {

    propiedad nombre

    propiedad color

    propiedad tamaño

 

    funcion comer() {

        // código para comer

    }

 

    funcion cantar() {

        // código para cantar

    }

 

    funcion volar() {

        // código para volar

    }

}

 

class Aguila implements Ave {

    propiedad nombre

    propiedad color

    propiedad tamaño

 

    funcion comer() {

        // código para comer

    }

 

    funcion cantar() {

        noHacerNada()

    }

 

    funcion volar() {

        // código para volar

    }

}

 

class Gallina implements Ave {

    propiedad nombre

    propiedad color

    propiedad tamaño

 

    funcion comer() {

        // código para comer

    }

 

    funcion cantar() {

        // código para cantar

    }

 

    funcion volar() {

        noHacerNada()

    }

}

 

En este ejemplo tenemos una interfaz llamada Ave con 3 acciones pero no todas las aves realizan esas tres acciones. Por ejemplo las águilas no cantan y las gallinas no vuelan. Pero si una clase implementa una interfaz está obligada a incluir esas funciones aunque no hagan nada.

Solución

La solución consiste en segregar la interfaz Ave en 3 interfaces más específicas.

 

interface Ave {

    funcion comer()

}

 

interface AveCantora {

    funcion cantar()

} 

 

interface AveVoladora {

    funcion volar()

}

 

class Loro implements Ave, AveCantora, AveVoladora {

    propiedad nombre

    propiedad color

    propiedad tamaño

 

    funcion comer() {

        // código para comer

    }

 

    funcion cantar() {

        // código para cantar

    }

 

    funcion volar() {

        // código para volar

    }

}

 

class Aguila implements Ave, AveVoladora {

    propiedad nombre

    propiedad color

    propiedad tamaño

 

    funcion comer() {

        // código para comer

    }

 

    funcion volar() {

        // código para volar

    }

}

 

class Gallina implements Ave, AveCantora {

    propiedad nombre

    propiedad color

    propiedad tamaño

 

    funcion comer() {

        // código para comer

    }

 

    funcion cantar() {

        // código para cantar

    }

}

 

Ahora cada clase sólo implementa las interfaces necesarias a sus capacidades por lo que no hay funciones que no hacen nada.

Con esta solución es sencillo incluir en un futuro por ejemplo aves que puedan nadar y cada clase sólo implementará las funciones necesarias.

Además con esta solución se mejora aún más el principio de responsabilidad única.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.