Los pri­n­ci­pios SOLID son cinco prácticas y di­re­c­tri­ces para un código limpio, fácil de mantener y flexible en la pro­gra­ma­ción basada en objetos. La apli­ca­ción y el cu­m­pli­mie­n­to de estos pri­n­ci­pios facilitan la co­m­pre­n­sión del diseño de software durante largos periodos de de­sa­rro­llo. De este modo, no solo se puede escribir mejor código, sino que también se puede mantener mejor el existente.

¿Qué son los pri­n­ci­pios SOLID?

Un buen código fuente comienza con reglas, pa­ra­di­g­mas de pro­gra­ma­ción y un estilo de pro­gra­ma­ción adecuado para conseguir un código eficiente y limpio. Esto es exac­ta­me­n­te lo que ga­ra­n­ti­zan los cinco pri­n­ci­pios SOLID, acuñados por Robert C. Martin, Bertrand Meyer y Barbara Liskov. Siguiendo ciertos pri­n­ci­pios en la pro­gra­ma­ción orientada a objetos (OOP) con lenguajes como Python o Java no solo es­cri­bi­rás mejor el código, sino que también co­n­se­gui­rás un ma­n­te­ni­mie­n­to más eficiente del mismo, un diseño de software so­s­te­ni­ble y flexible, y una mayor seguridad a largo plazo.

SOLID hace re­fe­re­n­cia, por un lado, a la base sólida de de­sa­rro­llo para todos aquellos que quieran aprender a programar. Por otro lado, al acrónimo se compone de las primeras letras de los cinco pri­n­ci­pios (por Michael Feathers):

  • Single Re­s­po­n­si­bi­li­ty Principle: un objeto debe tener una sola razón para cambiar, es decir, una sola re­s­po­n­sa­bi­li­dad.
  • Open Closed Principle: las clases deben estar abiertas para su extensión, pero cerradas para su mo­di­fi­ca­ción.
  • Liskov Su­b­s­ti­tu­tion Principle: las subclases deben ser su­s­ti­tui­bles por sus clases base sin afectar al co­m­po­r­ta­mie­n­to del programa.
  • Interface Se­gre­ga­tion Principle: los clientes no deben verse obligados a depender de in­te­r­fa­ces que no utilizan.
  • De­pe­n­de­n­cy Inversion Principle: los módulos de alto nivel no deben depender de módulos de bajo nivel, sino de ab­s­tra­c­cio­nes. Las ab­s­tra­c­cio­nes no deben depender de detalles, sino que los detalles deben depender de ab­s­tra­c­cio­nes.

¿Qué ventajas ofrecen los pri­n­ci­pios SOLID?

Sin reglas aparece el caos, afi­r­ma­ción que se hace evidente al programar. Incluso errores, im­pre­ci­sio­nes y omisiones pequeños pueden volver “inu­ti­li­za­ble” a largo plazo el código fuente. No se necesita mucho para esto: basta con clases complejas que di­fi­cu­l­tan la im­ple­me­n­ta­ción, o subclases que carecen de ciertas pro­pie­da­des de sus su­pe­r­cla­ses. Los pri­n­ci­pios SOLID ga­ra­n­ti­zan que se necesite la menor cantidad posible de re­pa­ra­ción de código a través de la re­fa­c­to­ri­za­ción.

Las ventajas de aplicar los pri­n­ci­pios SOLID incluyen:

  • Claridad, limpieza y belleza: el software y los códigos son más fáciles de entender, más co­m­pre­n­si­bles, más eficaces y, en de­fi­ni­ti­va, más agra­da­bles a la vista.
  • Facilidad de ma­n­te­ni­mie­n­to: la es­tru­c­tu­ra clara y despejada facilita el ma­n­te­ni­mie­n­to tanto del código nuevo como del que ha ido creciendo con el tiempo, incluso si hay múltiples partes in­te­re­sa­das.
  • Pe­r­so­na­li­za­ble, ampliable y re­uti­li­za­ble: una mejor le­gi­bi­li­dad, la reducción de co­m­ple­ji­da­des y re­s­po­n­sa­bi­li­da­des y la di­s­mi­nu­ción de las de­pe­n­de­n­cias de clases hacen que el código sea más fácil de editar, pe­r­so­na­li­zar, ampliar mediante in­te­r­fa­ces y re­uti­li­zar con fle­xi­bi­li­dad.
  • Menos propenso a errores: un código limpio con una es­tru­c­tu­ra sencilla ayuda a que los cambios en una parte no afecten in­di­re­c­ta­me­n­te a otras áreas o funciones.
  • Más seguro y fiable: con menos o ninguna vu­l­ne­ra­bi­li­dad, in­co­m­pa­ti­bi­li­dad o error, la fu­n­cio­na­li­dad y fia­bi­li­dad de los sistemas mejora, al igual que la seguridad.

Los pri­n­ci­pios SOLID de un vistazo

Los pri­n­ci­pios SOLID se en­cue­n­tran entre las reglas de oro de la buena pro­gra­ma­ción y, por tanto, deberían resultar fa­mi­lia­res a cua­l­quie­ra que se dedique a la pro­gra­ma­ción basada en objetos. Te pre­se­n­ta­mos los cinco pri­n­ci­pios en detalle.

SRP: Single Re­s­po­n­si­bi­li­ty Principle (Principio de Re­s­po­n­sa­bi­li­dad Única)

La de­fi­ni­ción original según Robert C. Martin en “Agile Software De­ve­lo­p­me­nt: Pri­n­ci­ples, Patterns and Practices” establece:

Cita

“Nunca debe haber más de una razón para cambiar una clase”

El SRP establece que solo debe aplicarse una re­s­po­n­sa­bi­li­dad a cada clase del OOP. Por lo tanto, solo debe haber un motivo para realizar cambios en la clase. Al contrario de lo que se suele entender, esto no significa que una clase o módulo solo pueda tener una tarea. Sin embargo, debería asumir la re­s­po­n­sa­bi­li­dad solo de tareas es­pe­cí­fi­cas que idea­l­me­n­te no se su­pe­r­po­n­gan con otras áreas.

La su­pe­r­po­si­ción de re­s­po­n­sa­bi­li­da­des, como pro­po­r­cio­nar funciones para di­fe­re­n­tes áreas co­me­r­cia­les, puede tener un impacto en la fu­n­cio­na­li­dad de la clase cuando se realizan cambios en una de esas áreas. Tener más de una re­s­po­n­sa­bi­li­dad y de­ma­sia­das de­pe­n­de­n­cias puede resultar en que un cambio en un área provoque varios cambios adi­cio­na­les o errores en el código.

Por lo tanto, el SRP tiene como objetivo de­sa­rro­llar módulos cohe­re­n­tes re­s­po­n­sa­bles de una tarea cla­ra­me­n­te co­m­pre­n­si­ble o de objetos cla­ra­me­n­te definidos. La es­tru­c­tu­ra cla­ra­me­n­te definida con de­pe­n­de­n­cias reducidas e im­ple­me­n­ta­cio­nes des­aco­pla­das permite realizar cambios y mo­du­la­ri­za­cio­nes po­s­te­rio­res de manera más fácil, rápida y sin co­m­pli­ca­cio­nes.

Nota

Las clases, también conocidas como tipos de objetos, son el elemento central en la pro­gra­ma­ción orientada a objetos (OOP). Pueden en­te­n­de­r­se como un plano con atributos para construir objetos reales similares en objetos de software. Por ello, las clases, también conocidas como módulos, a menudo se comparan con tipos de archivos.

OCP: Open Closed Principle (Principio de Apertura y Cierre)

Bertrand Meyer y Robert C. Martin, en “Object Oriented Software Co­n­s­tru­c­tion”, afirman lo siguiente sobre el OCP:

Cita

“Las entidades de software (clases, módulos, funciones, etc.) deben estar tanto abiertas para am­plia­cio­nes como cerradas para mo­di­fi­ca­cio­nes”

El OCP garantiza que no haya que re­es­cri­bir el software en su núcleo para aplicar cambios. Si se requieren mo­du­la­cio­nes profundas del código, existe el riesgo de que se produzcan errores sutiles y hediondez del código. Un código bien es­tru­c­tu­ra­do debe poder dotarse de in­te­r­fa­ces a través de las cuales pueda ampliarse con funciones adi­cio­na­les. Aquí, la palabra clave es la herencia de clases.

Las nuevas ca­ra­c­te­rí­s­ti­cas y ex­te­n­sio­nes con funciones y métodos cla­ra­me­n­te nuevos que deban im­ple­me­n­tar­se pueden acoplarse si­m­ple­me­n­te a una su­pe­r­cla­se en forma de subclases a través de una interfaz. De este modo, no es necesario “retocar” el código escrito y estable. Esto si­m­pli­fi­ca el ma­n­te­ni­mie­n­to y la co­n­se­r­va­ción de los programas y hace que la re­uti­li­za­ción de elementos de código estables sea mucho más eficiente gracias a las in­te­r­fa­ces.

LSP: Liskov Su­b­s­ti­tu­tion Principle (Principio de Su­s­ti­tu­ción de Liskov)

Barbara H. Liskov y Jeannette M. Wing, en “Beha­vio­ral Subtyping Using In­va­ria­nts and Co­n­s­trai­nts”, dicen sobre el LSP:

Cita

“Si q (x) es una propiedad del objeto x del tipo T, entonces q (y) debe cumplirse para todos los objetos del tipo S, donde S es un subtipo de T”.

Lo que suena críptico a primera vista es fácil de entender: las subclases enlazadas o ex­te­n­di­das deben funcionar como sus su­pe­r­cla­ses o clases base. Esto significa que cada subclase debe conservar las pro­pie­da­des de su re­s­pe­c­ti­va su­pe­r­cla­se por medio de la herencia y que estas pro­pie­da­des no deben mo­di­fi­car­se en la subclase. En principio, deben ser re­em­pla­za­bles. Las su­pe­r­cla­ses, en cambio, pueden mo­di­fi­car­se mediante cambios.

El clásico ejemplo del re­c­tá­n­gu­lo y el cuadrado de Robert C. Martin sirve para ex­pli­car­lo. En las clases de geometría se reconoce que todo cuadrado es un re­c­tá­n­gu­lo, pero no todo re­c­tá­n­gu­lo es un cuadrado. Más bien, un cuadrado comparte la propiedad “lados en ángulo recto” con la su­pe­r­cla­se de los re­c­tá­n­gu­los, pero tiene la propiedad adicional “lados de igual longitud”.

En pro­gra­ma­ción es diferente. En este caso, la su­po­si­ción de que clases similares o apa­re­n­te­me­n­te idénticas se re­la­cio­nan entre sí o dependen unas de otras conduce a errores, ma­le­n­te­n­di­dos y código poco claro. Por eso, en pro­gra­ma­ción, la clase “re­c­tá­n­gu­lo” no es un cuadrado y la clase “cuadrado” no es un re­c­tá­n­gu­lo. Ambas están “des­aco­pla­das” e im­ple­me­n­ta­das por separado. Sin una conexión integrada entre las clases, un ma­le­n­te­n­di­do no puede dar lugar a errores entre clases. Esto aumenta la seguridad y la es­ta­bi­li­dad a la hora de sustituir im­ple­me­n­ta­cio­nes en subclases o su­pe­r­cla­ses sin re­pe­r­cu­sio­nes.

ISP: Interface Se­gre­ga­tion Principle (Principio de Se­gre­ga­ción de In­te­r­fa­ces)

En “The Interface Se­gre­ga­tion Principle”, Robert C. Martin define el ISP de la siguiente manera:

Cita

“Los clientes no deben verse obligados a depender de in­te­r­fa­ces que no utilizan”

El ISP establece que no se debe obligar a los usuarios a utilizar in­te­r­fa­ces que no necesitan. En otras palabras: para pro­po­r­cio­nar a los clientes las funciones de de­te­r­mi­na­das clases, se adaptan nuevas in­te­r­fa­ces más pequeñas a re­qui­si­tos es­pe­cí­fi­cos. Así se evita que las in­te­r­fa­ces se hagan demasiado grandes y se crean fuertes de­pe­n­de­n­cias entre clases. La ventaja: un software con clases des­aco­pla­das y varias in­te­r­fa­ces pequeñas adaptadas a re­qui­si­tos es­pe­cí­fi­cos es más fácil de mantener.

DIP: De­pe­n­de­n­cy Inversion Principle (Principio de Inversión de la De­pe­n­de­n­cia)

Según Robert C. Martin en “The De­pe­n­de­n­cy Inversion Principle”, el quinto y último elemento de los pri­n­ci­pios SOLID es el siguiente:

Cita

“A. Los módulos de alto nivel no deben depender de los de bajo nivel. Ambos deben depender de ab­s­tra­c­cio­nes. B. Las ab­s­tra­c­cio­nes no deben depender de los detalles. Los detalles deben depender de las ab­s­tra­c­cio­nes”.

El DIP garantiza que las funciones y de­pe­n­de­n­cias concretas en los niveles de código fuente se basen en in­te­r­fa­ces ab­s­tra­c­tas y no entre sí. Para ex­pli­car­lo: las ar­qui­te­c­tu­ras de software pueden dividirse a grandes rasgos en niveles de usuario su­pe­rio­res y niveles ab­s­tra­c­tos in­fe­rio­res o más profundos. Ló­gi­ca­me­n­te, cabe suponer que la base abstracta determina el co­m­po­r­ta­mie­n­to de los niveles su­pe­rio­res. Sin embargo, el DIP considera que esto es propenso a errores, ya que los niveles su­pe­rio­res dependen de los niveles in­fe­rio­res.

En lugar de vincular los niveles su­pe­rio­res con los in­fe­rio­res, las clases de los niveles altos y bajos deben depender de in­te­r­fa­ces ab­s­tra­c­tas in­te­r­me­dias. Las in­te­r­fa­ces recuperan de los niveles in­fe­rio­res las fu­n­cio­na­li­da­des ne­ce­sa­rias en los niveles su­pe­rio­res y las ponen a su di­s­po­si­ción. De esta forma, se evita una “jerarquía de abajo arriba” de de­pe­n­de­n­cias, que puede dar lugar a errores en el código con el paso del tiempo. Esto facilita la re­uti­li­za­ción de los módulos y permite in­tro­du­cir cambios en las clases in­fe­rio­res sin afectar a los niveles su­pe­rio­res.

Web Hosting
El hosting que crece con tu proyecto
  • Tiempo de actividad de 99.99 % y seguridad ga­ra­n­ti­za­da
  • Aumenta el re­n­di­mie­n­to según el tráfico de tu página web
  • Incluye dominio, SSL, e-mail y soporte 24/7

¿Qué ocurre en caso de in­cu­m­pli­mie­n­tos de los pri­n­ci­pios SOLID?

Un código bonito y fácil de leer que facilite al máximo el ma­n­te­ni­mie­n­to debería ser el objetivo de todo de­sa­rro­llo de software. Sin embargo, si se olvidan di­re­c­tri­ces como los pri­n­ci­pios SOLID, el código envejece muy mal debido a vu­l­ne­ra­bi­li­da­des, re­du­n­da­n­cias, errores acu­mu­la­dos y de­ma­sia­das de­pe­n­de­n­cias. En el peor de los casos, el código se vuelve inu­ti­li­za­ble con el tiempo. Este es un problema im­po­r­ta­n­te en el de­sa­rro­llo ágil de software, ya que suele haber muchas personas tra­ba­ja­n­do en código complejo.

Las co­n­se­cue­n­cias de un código de­s­cui­da­do o ma­n­te­ni­mie­n­to de­fi­cie­n­te incluyen:

  • Code Smell: las de­bi­li­da­des heredadas de un código poco limpio, conocidas como code smell o “hediondez del código”, pueden provocar fallos de fu­n­cio­na­mie­n­to y programas in­co­m­pa­ti­bles.
  • Code Rot: si no se realiza el ma­n­te­ni­mie­n­to o la re­pa­ra­ción mediante re­fa­c­to­ri­za­ción o una costosa revisión de código, el código puede “podrirse” me­ta­fó­ri­ca­me­n­te y perder co­m­ple­ta­me­n­te su fu­n­cio­na­li­dad. Otra de­no­mi­na­ción para un código ilegible y confuso es la de “código espagueti”.
  • Vu­l­ne­ra­bi­li­da­des de seguridad: además de los fallos, el ma­n­te­ni­mie­n­to co­m­pli­ca­do o las in­co­m­pa­ti­bi­li­da­des, también hay riesgos de seguridad, que pueden dar al malware la opo­r­tu­ni­dad de explotar vu­l­ne­ra­bi­li­da­des o ataques de día cero.

¿Quién de­sa­rro­lló los pri­n­ci­pios SOLID?

El origen de los pri­n­ci­pios SOLID se encuentra en varios pri­n­ci­pios que introdujo por primera vez Robert C. Martin (“Uncle Bob”), uno de los ini­cia­do­res de la pro­gra­ma­ción ágil, en su ensayo “Design Pri­n­ci­ples and Design Patterns” en 2000. El grupo de cinco pri­n­ci­pios SOLID fue acuñado por Robert C. Martin, Bertrand Meyer y Barbara Liskov. El pegadizo acrónimo formado por las cinco letras iniciales de los pri­n­ci­pios fue propagado a su vez por Michael Feathers reor­de­na­n­do cinco de los pri­n­ci­pios ese­n­cia­les.

¿Qué pri­n­ci­pios de pro­gra­ma­ción similares existen?

En el de­sa­rro­llo de software, los pri­n­ci­pios re­pre­se­n­tan di­re­c­tri­ces y re­co­me­n­da­cio­nes de actuación generales o muy es­pe­cí­fi­cas similares a los pri­n­ci­pios SOLID, que ofrecen un conjunto de pri­n­ci­pios para el paradigma de la pro­gra­ma­ción orientada a objetos. Otros pri­n­ci­pios de pro­gra­ma­ción para código limpio incluyen:

  • Principio DRY (Don’t repeat yourself) para funciones con una única y exclusiva re­pre­se­n­ta­ción.
  • Principio KISS (Keep it simple, stupid) para un código lo más sencillo posible.
Ir al menú principal