Estamos avanzando con nuestro estudio de los principios de diseño SOLID, y ahora hemos llegado a L. La L significa Principio de sustitución de Liskov o LSP y lleva el nombre de la creadora del principio, Barbara Liskov . La definición formal es muy detallada, por lo que en este tutorial, cubriremos el tema como si estuviéramos escribiendo el primer borrador del libro, "El principio de sustitución de Liskov para tontos". Aprendamos un poco más sobre este principio ahora.
Tienes la abstracción incorrecta
SOLID tiene que ver con la abstracción y, sobre todo, con el uso correcto de las interfaces. SOLID está completamente entrelazado y, al final de todo, casi podría decir, "Codifique para una interfaz", y eso sería todo. Siguiente lección. Aquí hay uno divertido.
Si parece un pato, grazna como un pato, pero necesita baterías, probablemente tengas la abstracción incorrecta.
-La Internet
Creo que la idea a la que se llega es que, una vez que empiece a depender de las abstracciones en sus programas, se vuelve importante que esas abstracciones puedan intercambiarse libremente sin causar roturas en el programa. Stack Overflow tiene esta cita en la respuesta más popular a la pregunta.
Las funciones que usan punteros o referencias a clases base deben poder usar objetos de clases derivadas sin saberlo.
-Robert Martín
Resulta que esto en realidad proviene de Robert Martin, como una paráfrasis de la propia definición oficial de Barbara Liskov aquí:
Lo que se busca aquí es algo como la siguiente propiedad de sustitución: si para cada objeto o1 de tipo S hay un objeto o2 de tipo T tal que para todos los programas P definidos en términos de T, el comportamiento de P no cambia cuando o1 es sustituido para o2 entonces S es un subtipo de T.
-Barbara Liskov
En nuestro pequeño mundo de trabajo con inyección de dependencia y sugerencias de tipo en PHP y Laravel, esto significaría algo como esto. Dada una clase A
que depende de B
, si pasamos un C
cuando inicializamos A
, todo debería funcionar perfectamente. Expliquemos esto en código. Queremos escribir un programa, y el único objetivo es que genere una cadena que diga "haciendo algo". Aquí está nuestro código de cliente o nuestro programa.
Perfecto. Escribimos un programa que hace lo que queremos que haga. Ahora, el Principio de sustitución de Liskov establece que deberíamos poder crear una nueva clase que se extiendaB
, y cuando pasemos esa instancia derivada , en lugar de la original, todo seguirá funcionando. Otra forma de decir esto es que las clases derivadas deben ser sustituibles por sus clases base . Con eso, creemos una nueva claseC
que se extiendaB
.
Ahora, sustituyamos la clase secundaria por la clase base en nuestro código de cliente.
Agradable. Nuestro programa todavía funciona perfectamente, aunque pasamos unC
(derivado) en lugar de unB
(base). Tenga en cuenta que ni siquiera cambiamos nada en ClassA
, todavía espera recibir una instancia de classB
en su constructor. Para todos los efectos, elA
objeto básicamente todavía cree que está llamando a un método en unB
objeto cuando en realidad está llamando a un método en unC
objeto. Este es el principio de sustitución de Liskov en acción. Rompamos ahora el LSP con una nueva claseD
que también se extiendeB
.
Ahora podemos volver a llamar a nuestro código de cliente y pasar un en D
lugar de un B
o C
.
Fallar. Técnicamente, el programa aún se ejecuta, pero no estamos cumpliendo los objetivos del programa. No se está comportando como se esperaba. Recuerde que se supone que nuestro programa da como resultado "hacer algo". Cuando pasamos en la clase baseB
, muestra correctamente "haciendo algo". De hecho, cuando sustituimos nuestra clase base deB
por una clase derivadaC
, nuestro programa todavía muestra "haciendo algo", por lo que funciona según lo diseñado y pasa el LSP . Finalmente, pasamos unaD
instancia y, de repente, nuestro programa muestra "haciendo algo MÁS". Cambiamos nuestra clase base con una clase derivada y el programa se rompió. Este es el ejemplo más básico del principio de sustitución de Liskov que se me ocurre.
El principio de sustitución de Liskov en el mundo real
Como no tengo un doctorado en ciencias de la computación como Barbara y algunas de las otras grandes mentes que idearon los patrones en diseño sólido, a menudo tengo que dividirlo en algo tan simple que nunca lo usarías en la realidad. Sin embargo, lo que esto logra es obligar a uno a pensar en el concepto y procesarlo hasta que se entienda lo suficiente como para dar un ejemplo en términos muy básicos. Esto nos permite aplicar el principio a más aplicaciones del mundo real.
Más información sobre el principio de sustitución de Liskov
Stack Overflow Thread sobre el principio de sustitución de Liskov
El principio de sustitución de Liskov según Robert Martin
Cunningham y Cunningham discuten el principio de sustitución de Liskov
Gran presentación de Youtube sobre el principio de sustitución de Liskov
Aprenda sobre el poder de la abstracción de la propia Barbara
Resumen del principio de sustitución de Liskov
Como la mayoría de las ideas presentadas en la programación sólida, el principio de sustitución de Liskov tiene como objetivo hacer programas más robustos y fáciles de mantener a lo largo del tiempo. En última instancia, el objetivo principal de LSP es que cualquier clase derivada se pueda utilizar de forma transparente y con un 100% de confianza en cualquier lugar donde se utilice la clase original. Si intercambia la clase base con una clase derivada y el programa falla, sabrá que rompe el LSP.
0 Comentarios