Liskov Substitution Principle (LSP)
Definición: Las instancias de una subclase deben poder reemplazar a las instancias de la clase base sin afectar la correctitud del programa. Code Smell Relacionado:
- Jerarquías de Clase Incorrectas
- Métodos que Lanzan UnsupportedOperationException
- Comprobaciones de Tipo (instanceof, is, etc.)
Técnicas de Refactorización:
- Replace Inheritance with Delegation: Sustituir herencia por composición
- Extract Interface: Extraer interfaces comunes
- Replace Conditional with Polymorphism: Eliminar comprobaciones de tipo
Ejemplo de Refactorización (Java):
class Rectangle {
protected int width;
protected int height;
public void setWidth(int width) { this.width = width; }
public void setHeight(int height) { this.height = height; }
public int getArea() { return width * height; }
}
class Square extends Rectangle {
@Override
public void setWidth(int width) {
this.width = width;
this.height = width; // Violación de LSP
}
@Override
public void setHeight(int height) {
this.width = height; // Violación de LSP
this.height = height;
}
}
interface Shape {
int getArea();
}
class Rectangle implements Shape {
private int width;
private int height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public void setWidth(int width) { this.width = width; }
public void setHeight(int height) { this.height = height; }
@Override
public int getArea() { return width * height; }
}
class Square implements Shape {
private int side;
public Square(int side) {
this.side = side;
}
public void setSide(int side) { this.side = side; }
@Override
public int getArea() { return side * side; }
}