Principio de Sustitución de Liskov como cumplir con el

Sustitucion de Liskov

El Principio de Sustitución de Liskov es parte los principios SOLID cuya implementación sirve para aumentar la calidad del código.

Este principio es definido de la siguiente manera:

Si a un método “q” le podemos pasar objetos “x” de la clase “T”, el método hace correctamente su función. — Si tenemos una clase “S” que hereda de la clase “T”. Entonces un objeto “y” de la clase “S” debería ser capaz de pasarse a la función “q” y ésta funcionará igualmente.

Aun seguimos con dudas, ¿no? afortunadamente una explicación sacada de wikipedia nos puede ayudar un poco.

Cada clase que hereda de otra puede usarse como su padre sin necesidad de conocer las diferencias entre ellas.

Ahora vamos a explicar el siguiente ejemplo ya clásico.

Tenemos la clase Rectángulo con sus respectivos settets y getters y un método para calcular el área.

public class Rectangle {
int width;
int height;
public double calculateArea(){
return height * width;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}

Ahora tenemos la Clase Cuadrado y suponemos que un cuadrado es un tipo de rectángulo con los lados del mismo tamaño ¿No es verdad?

public class Square extends Rectangle {
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.height = width;
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
this.width = height;
}
}

Ahora que pasa si queremos hacer una prueba

static void runLiskovFail() {
Rectangle rectangle = new Rectangle();
rectangle.setHeight(5);
rectangle.setWidth(2);
System.out.println("rectangle area:" +rectangle.calculateArea());
Square square = new Square();
square.setHeight(5);
square.setWidth(6);
System.out.println("square area:"+square.calculateArea());
}

El resultado seria el siguiente:

rectangle area:10.0

square area:36.0

Aquí encontramos el error ya el método ocupa solo un numero para hacer el calculo y nos obliga a realizar el código con comprobaciones o regresar excepciones. Esto significa que nuestra abstracción es incorrecta un cuadrado no es un rectángulo.

Image for post

Una implementación correcta del Principio de Sustitución de Liskov seria la siguiente:

Imaginemos que tenemos una aplicación que realiza el calculo la calificación de las materias de una escuela con base en tus tareas y tu examen. Pero cada maestro determina cual es el porcentaje de valor de ellos.

Podemos crear una interfaz con un método que reciba ambos parámetros.

public interface ILesson {
public double calculateScore(double homework, double exam);
}

Después creamos clases especificas que implementen esta interfaz y sobrescriban el método asignando el porcentaje de valor al examen y las tareas.

public class Geometry implements ILesson{
public double calculateScore(double homework, double exam) {
return (homework*.2)+(exam*.8);
}
}
public class History implements ILesson{
public double calculateScore(double homework, double exam) {
return (homework*.3)+(exam*.7);
}
}

Ahora probamos el codigo:

static void runLiskovOk() {
ILesson scoreGeometry = new Geometry();
System.out.println("Score Geometry:"+scoreGeometry.calculateScore(8.0,6.0));
ILesson scoreHistory = new History();
System.out.println("Score History:"+scoreHistory.calculateScore(8.0,8.0));
}

El resultado obtenido:

Score Geometry:6.4

Score History:8.0

Esto cumple perfectamente con el principio ya que ambas clases pueden usarse sin distinción entre ellas.

Puedes encontrar el código completo en el siguiente enlace de GitHub.

https://github.com/eduesqui/solidExamples

0 Shares:
You May Also Like