¿Cómo aplicar correctamente el principio de sustitución de Liskov?
El principio de sustitución de Liskov es uno de los pilares fundamentales en la programación orientada a objetos y uno de los principios SOLID. Su aplicación garantiza que las clases derivadas puedan reemplazar sin problemas a sus clases base o superclases sin alterar el comportamiento esperado del programa. En otras palabras, las instancias de subclases deben comportarse de manera coherente con lo esperado del tipo base. Esto asegura flexibilidad y funcionalidad en nuestros proyectos de software.
¿Qué problemas existían en el código original?
El caso presentado describe una aplicación con dos tipos de empleados: contractor y full-time. Había ciertos problemas fundamentales en la estructura del código:
-
Propiedad de horas extras inadecuadamente generalizada: La clase base Employee
contenía una propiedad de horas extras que solo es relevante para empleados full-time, no para contractors. Esto viola el principio porque un subtipo no debería llevar propiedades o métodos de los cuales no haga uso.
-
Cálculo de salario genérico: Un método pretendía calcular el salario de todos los tipos de empleados sin considerar sus diferencias. Esto impide que el sistema pueda escalar para nuevos tipos de empleados y es una clara violación del principio de responsabilidad única.
¿Cómo se debe reestructurar la clase Employee?
Para solucionar estos problemas, es esencial hacer algunos cambios en el diseño de las clases:
-
Eliminar la propiedad de las horas extras de la clase base Employee
. Esto se debe a que no todos los subtipos hacen uso de esta propiedad.
public abstract class Employee {
public string FullName { get; set; }
public int HoursWorked { get; set; }
public abstract decimal CalculateSalary();
}
-
Mover la implementación del cálculo de salario a cada una de las subclases, para que cada una se encargue de su método de cálculo específico.
public class EmployeeFullTime : Employee {
public int ExtraHours { get; set; }
public override decimal CalculateSalary() {
return (HoursWorked + ExtraHours) * 50;
}
}
public class EmployeeContractor : Employee {
public override decimal CalculateSalary() {
return HoursWorked * 40;
}
}
¿Cuáles son los beneficios de aplicar el principio de Liskov?
Al reestructurar el código según el principio de sustitución de Liskov, se obtiene un sistema más flexible y escalable:
-
Reutilización y escalabilidad: Introducir nuevos tipos de Employee
es más sencillo y libre de conflictos porque cada subtipo es responsable de su comportamiento específico.
-
Código más limpio y mantenible: Elimina las verificaciones y condicionales innecesarias en la clase base, lo que simplifica el código y reduce la complejidad.
-
Cumplimiento de expectativas de la superclase: Los subtipos pueden sustituirse por la clase base sin alterar el comportamiento del programa, lo que reduce errores en el sistema.
¿Cómo verificar nuestras implementaciones?
Siempre es buena práctica, después de integrar tales cambios, realizar pruebas de compilación y de ejecución para asegurar que el sistema sigue siendo funcional y se comporta según lo esperado.
-
Compilar el código para revisar que no haya errores de sintaxis.
dotnet build
-
Ejecutar el programa para validar los resultados reales.
dotnet run
Al seguir estos pasos, te aseguras de que tu sistema cumpla con el principio de sustitución de Liskov, lo que traerá como resultado un código más robusto y preparado para aumentar su complejidad de manera controlada. ¡Continúa con tu aprendizaje en SOLID y sigue mejorando tus habilidades en el desarrollo de software!
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?