¿Qué es el principio de sustitución de Liskov?
El principio de sustitución de Liskov es uno de los cinco principios SOLID que buscan una mejor estructura de códigos orientados a objetos. Fue formulado por Barbara Liskov, una figura destacada en la ciencia de la computación, y más tarde popularizado por Robert Martin en el libro "Clean Code". Este principio establece que los subtipos deben ser reemplazables por su tipo base sin afectar el comportamiento del sistema.
En otras palabras, si una clase A
es un subtipo de la clase B
, los objetos de tipo A
deben poder sustituir a los objetos de tipo B
sin alterar la correcta ejecución de un programa. Esta es la esencia del principio: garantizar que los subtipos respeten las propiedades y el comportamiento del tipo base.
¿Cómo se aplica el principio de sustitución de Liskov en la práctica?
Para aplicar este principio, es fundamental asegurarnos de que:
- Todos los subtipos implementen todas las propiedades y métodos del tipo base.
- Las propiedades de los tipos se comporten de manera consistente en los subtipos, asegurando que cualquier cambio no afecte la lógica del sistema.
- La lógica que distingue a un subtipo sea relevante y no rompa las expectativas del tipo base.
Vamos a ilustrarlo con un ejemplo práctico de implementación utilizando el panorama dado de empleados.
Ejemplo práctico del principio con empleados
En un sistema que gestiona empleados, tenemos dos tipos: Contractor
y FullTime
. El FullTime
tiene derecho a horas extra, mientras que el Contractor
no. La meta es ajustar el código para que todos los empleados puedan ser tratados de manera uniforme respecto a sus tipos.
Código inicial que no sigue SOLID
Supongamos que tenemos la siguiente implementación simplificada:
class Empleado:
def calcular_salario(self, horas):
pass
class FullTime(Empleado):
def calcular_salario(self, horas):
return horas * 50
class Contractor(Empleado):
def calcular_salario(self, horas):
return horas * 40
En este ejemplo, el método calcular_salario
está correctamente implementado en ambos subtipos, pero aún podemos mejorar su adherencia al principio SOLID al abordar las horas extra.
Ajuste para cumplir el principio de sustitución de Liskov
Vamos a extender estas clases para cumplir completamente el principio:
class Empleado:
def calcular_salario(self, horas):
pass
def horas_extra(self, horas):
return 0
class FullTime(Empleado):
def calcular_salario(self, horas):
return (horas + self.horas_extra(horas)) * 50
def horas_extra(self, horas):
return horas * 1.5
class Contractor(Empleado):
def calcular_salario(self, horas):
return horas * 40
Reflexiones finales sobre el ejemplo
Con esta refactorización, nos aseguramos de que ambos tipos, FullTime
y Contractor
, puedan ser intercambiados sin que afecten la lógica de cálculo de salario. Contractor
simplemente hereda la implementación predeterminada para la falta de horas extras, mientras que FullTime
añade su propia lógica.
Al implementar el principio de sustitución de Liskov de esta manera, hacemos que el código sea más flexible, reutilizable y fácil de mantener. La adherencia a los principios SOLID no sólo mejora la calidad del código, sino que también fortalece su integridad a medida que el sistema crece y evoluciona. ¡Sigue estudiando y aplicando estos principios para mejorar continuamente como desarrollador!
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?