SOLID es un acrónimo de cinco principios de diseño orientado a objetos que ayudan a escribir código que se pueda cambiar y ampliar sin romperlo. S — Responsabilidad única: cada clase debe tener una sola razón para cambiar, es decir, ocuparse de una sola cosa (una clase que a la vez calcula un informe y lo imprime hace demasiado). O — Abierto/cerrado: el código debe estar abierto a extenderse (agregar comportamiento nuevo) pero cerrado a modificarse (sin tocar lo que ya funciona); se logra añadiendo clases nuevas en vez de llenar de if las existentes. L — Sustitución de Liskov: si algo espera un tipo base, cualquier subtipo debe poder ocupar su lugar sin sorpresas (si Cuadrado hereda de Rectángulo pero rompe su comportamiento, viola este principio). I — Segregación de interfaces: es mejor tener varias interfaces pequeñas y específicas que una enorme que obliga a implementar métodos que no se usan. D — Inversión de dependencias: los módulos deben depender de abstracciones (interfaces), no de implementaciones concretas, para poder cambiar las piezas sin reescribir todo. El objetivo común es reducir el acoplamiento y aumentar la cohesión, de modo que el software resista el cambio. No son reglas rígidas: son guías con criterio, y aplicarlas a ciegas puede sobre-complicar tanto como ignorarlas.
Ver índice de contenidos
Qué es SOLID
SOLID es un acrónimo que agrupa cinco principios de diseño orientado a objetos, popularizados por Robert C. Martin. No son sintaxis ni reglas del lenguaje: son criterios de diseño que buscan un mismo fin, que el código sea fácil de cambiar a medida que el software crece, reduciendo el acoplamiento (cuánto depende una pieza de otra) y aumentando la cohesión (que cada pieza haga una cosa bien).
Conviene ubicar SOLID entre temas vecinos. Los patrones de diseño son soluciones concretas a problemas recurrentes (a menudo materializan principios SOLID). Clean Code abarca la legibilidad del código a pequeña escala (nombres, funciones cortas). SOLID, en cambio, opera en el nivel del diseño de clases y sus relaciones: cómo se reparten responsabilidades y dependencias. Se complementan.
Los cinco principios
Uno a uno, con la idea central y un ejemplo:
| Principio | Idea | Ejemplo de violación |
|---|---|---|
| S — Responsabilidad única | Una clase, una razón para cambiar | Una clase que calcula un informe y lo imprime |
| O — Abierto/cerrado | Extender sin modificar lo existente | Añadir un if más cada vez que aparece un caso |
| L — Sustitución de Liskov | Un subtipo debe poder reemplazar al base | Cuadrado que rompe el comportamiento de Rectángulo |
| I — Segregación de interfaces | Interfaces pequeñas y específicas | Una interfaz enorme con métodos que nadie usa |
| D — Inversión de dependencias | Depender de abstracciones, no de concretos | Un servicio que instancia directamente una base de datos concreta |
Un ejemplo que los une
Imaginá un servicio que envía notificaciones. Si la clase arma el mensaje, decide el canal y habla directamente con el proveedor de email (S violado: hace de todo), y cada canal nuevo (SMS, push) se agrega con otro if (O violado), y depende de la clase concreta ProveedorEmailConcreto (D violado)… ese servicio se vuelve un nudo. La versión SOLID: una interfaz Canal con un método enviar(), una clase por canal, y el servicio dependiendo de la interfaz. Agregar push es crear una clase nueva, sin tocar nada. Eso es el objetivo: que el cambio sea barato.
Cuándo aplicarlos (y cuándo no)
SOLID no es una lista de verificación que haya que cumplir en cada línea. Son guías que ganan valor cuando el código va a cambiar y crecer. En un script de veinte líneas que corre una vez, aplicar los cinco principios sobra y añade complejidad inútil.
Aplicar SOLID de forma dogmática lleva a la sobreingeniería: interfaces para todo, capas de abstracción que nadie va a intercambiar, indirecciones que hacen el código más difícil de seguir sin ningún beneficio real. La pregunta útil no es «¿cumple SOLID?», sino «¿este código va a necesitar cambiar por aquí, y si cambia, cuánto duele?». Donde el cambio es probable, SOLID paga; donde no, la simplicidad gana. Como el resto del diseño, se aplica con criterio, midiendo el coste-beneficio de cada abstracción frente a la simplicidad del código limpio.
Errores frecuentes
- Aplicar SOLID a todo por dogma. Genera sobreingeniería; los principios pagan donde el cambio es probable.
- Confundir «una responsabilidad» con «un método». Responsabilidad es una razón para cambiar, no una acción suelta.
- Crear interfaces que nunca tendrán una segunda implementación. Abstracción sin propósito es solo indirección.
- Heredar rompiendo el comportamiento del padre. Viola Liskov; si el subtipo no encaja, la herencia está mal planteada.
- Interfaces gigantes que lo abarcan todo. Obligan a implementar métodos vacíos; mejor varias pequeñas.
- Depender de clases concretas donde la pieza va a cambiar. Ata el código y dificulta las pruebas.
- Tratar SOLID como sinónimo de código limpio. Es diseño de clases; la legibilidad es otra cosa complementaria.
Preguntas frecuentes
¿Qué significan las siglas SOLID?
SOLID es un acrónimo formado por las iniciales de cinco principios de diseño orientado a objetos, cada una de cuyas letras corresponde a un principio concreto. La letra ese corresponde al principio de responsabilidad única, que sostiene que cada clase debe tener una sola responsabilidad, entendida como una única razón para cambiar, de modo que se ocupe de una sola cosa bien definida. La letra o corresponde al principio abierto cerrado, que sostiene que el código debe estar abierto a la extensión pero cerrado a la modificación, es decir, que se debe poder añadir comportamiento nuevo sin necesidad de tocar el código que ya funciona. La letra ele corresponde al principio de sustitución de Liskov, que sostiene que si un fragmento de código espera un objeto de un tipo base, debe poder recibir en su lugar cualquier subtipo sin que el comportamiento se rompa ni se produzcan sorpresas. La letra i corresponde al principio de segregación de interfaces, que sostiene que es preferible tener varias interfaces pequeñas y específicas antes que una única interfaz enorme que obligue a las clases a implementar métodos que no necesitan. Y la letra de corresponde al principio de inversión de dependencias, que sostiene que los módulos deben depender de abstracciones, es decir de interfaces, en lugar de depender de implementaciones concretas, de manera que las piezas puedan cambiarse sin reescribir todo. Estos cinco principios fueron recopilados y popularizados por Robert C. Martin, y el acrónimo SOLID fue acuñado posteriormente como forma cómoda de recordarlos. Todos ellos persiguen un objetivo común, que es lograr un código con bajo acoplamiento y alta cohesión, capaz de resistir el cambio a lo largo del tiempo, y conviene entenderlos como guías de diseño que se aplican con criterio y no como reglas rígidas de obligado cumplimiento en cada línea de código.
¿Qué es el principio de responsabilidad única?
El principio de responsabilidad única, que corresponde a la letra ese de SOLID, establece que cada clase debe tener una sola responsabilidad, lo que suele formularse diciendo que una clase debe tener una única razón para cambiar. La idea es que cada clase se ocupe de una sola cosa bien delimitada, en lugar de acumular funciones diversas que no tienen relación entre sí. Para entender qué se considera una responsabilidad, la clave está en pensar en las razones por las que el código podría necesitar modificarse: si una misma clase puede tener que cambiar por motivos distintos e independientes, probablemente esté asumiendo más de una responsabilidad. El ejemplo típico de violación es una clase que, por un lado, calcula o genera un informe con cierta lógica de negocio y, por otro lado, se encarga también de darle formato e imprimirlo o guardarlo en un archivo. Esa clase tiene al menos dos razones para cambiar, una si cambian las reglas del informe y otra si cambia el formato de salida, y esas dos preocupaciones no deberían estar mezcladas. La solución conforme al principio es separar esas responsabilidades en clases distintas, por ejemplo una que se ocupe del cálculo y otra que se ocupe de la presentación, de modo que cada una pueda evolucionar de forma independiente sin afectar a la otra. Cumplir este principio aporta varios beneficios: las clases resultan más pequeñas, más fáciles de entender y de probar, los cambios quedan localizados y se reduce el riesgo de que modificar una cosa rompa otra sin relación. Conviene, eso sí, no confundir responsabilidad única con tener un solo método, porque una responsabilidad puede englobar varias acciones relacionadas; lo que importa es la cohesión, es decir, que todo lo que hace la clase gire en torno a un mismo propósito y responda a una misma razón de cambio. Aplicado con sentido común, este principio es uno de los más útiles y de los que más ayuda a mantener el código ordenado.
¿Qué es la inversión de dependencias?
El principio de inversión de dependencias, que corresponde a la letra de de SOLID, establece que los módulos deben depender de abstracciones y no de implementaciones concretas, y más concretamente que los módulos de alto nivel, que contienen la lógica importante, no deben depender directamente de los módulos de bajo nivel, que contienen los detalles, sino que ambos deben depender de abstracciones. En términos prácticos, esto significa que en lugar de que una clase cree o utilice directamente otra clase concreta, debe apoyarse en una interfaz o abstracción que esa clase concreta implementa. El nombre de inversión se refiere a que se invierte el sentido habitual de la dependencia: normalmente el código de alto nivel dependería del de bajo nivel, pero con este principio se hace que el de bajo nivel dependa de una abstracción definida en función de las necesidades del de alto nivel. Un ejemplo ilustrativo es el de un servicio que necesita guardar datos: si el servicio instancia y utiliza directamente una clase concreta de acceso a una base de datos específica, queda atado a esa tecnología, y cambiarla o probar el servicio de forma aislada se vuelve difícil. Aplicando el principio, el servicio depende de una interfaz de almacenamiento con las operaciones que necesita, y la implementación concreta para esa base de datos concreta se le proporciona desde fuera; así se puede cambiar la implementación, por ejemplo a otra base de datos o a una versión falsa para pruebas, sin tocar el servicio. Este principio está estrechamente relacionado con la técnica de la inyección de dependencias, que es la forma habitual de proporcionar desde fuera las implementaciones concretas que un módulo necesita. Los beneficios de la inversión de dependencias son un menor acoplamiento entre las piezas del sistema, una mayor facilidad para sustituir componentes y una mayor testabilidad, ya que se pueden reemplazar las dependencias reales por sustitutos controlados en las pruebas. Como con el resto de SOLID, conviene aplicarlo donde de verdad aporta, es decir, donde es probable que la implementación concreta cambie o donde se necesita aislar para probar, y no crear abstracciones por sistema donde nunca habrá una segunda implementación.
¿SOLID es lo mismo que los patrones de diseño?
No, SOLID y los patrones de diseño no son lo mismo, aunque están estrechamente relacionados y a menudo se estudian juntos porque se complementan. SOLID es un conjunto de cinco principios de diseño orientado a objetos, es decir, criterios generales o guías que orientan cómo repartir responsabilidades y dependencias entre las clases para que el software sea fácil de cambiar y mantener; son ideas de alto nivel sobre qué cualidades debe tener un buen diseño, como el bajo acoplamiento y la alta cohesión. Los patrones de diseño, en cambio, son soluciones concretas y reutilizables a problemas de diseño que aparecen de forma recurrente, con una estructura más o menos definida que se puede aplicar cuando se reconoce el problema que resuelven; ejemplos conocidos son el patrón estrategia, el patrón observador, el patrón fábrica o el patrón adaptador, cada uno pensado para una situación típica. La relación entre ambos es que los patrones de diseño suelen ser formas concretas de materializar o respetar los principios SOLID: muchos patrones, al aplicarse, producen diseños que cumplen naturalmente principios como el abierto cerrado o la inversión de dependencias. Dicho de otro modo, SOLID te dice qué propiedades buscar en el diseño, y los patrones te ofrecen recetas probadas que a menudo consiguen esas propiedades. Conviene además no confundir ninguno de los dos con la idea de código limpio, que se refiere más a la legibilidad y calidad del código a pequeña escala, como los buenos nombres, las funciones cortas y la claridad, y que opera en un nivel distinto al del diseño de clases y sus relaciones. En resumen, SOLID son principios, los patrones son soluciones concretas que suelen respetar esos principios, y el código limpio es una cualidad de legibilidad complementaria; conocer los tres y entender cómo encajan ayuda a diseñar mejor software, pero son conceptos diferentes que no deben mezclarse.
¿Es obligatorio aplicar SOLID en todo proyecto?
No, no es obligatorio aplicar SOLID en todo proyecto ni en cada parte del código, porque SOLID no es un conjunto de reglas de obligado cumplimiento sino una colección de guías de diseño cuyo valor depende del contexto. El objetivo de estos principios es facilitar el cambio y el crecimiento del software reduciendo el acoplamiento, de modo que aportan más cuanto más probable es que el código tenga que cambiar y evolucionar con el tiempo, como ocurre en aplicaciones grandes, de larga vida o mantenidas por equipos. En cambio, en un script pequeño que se ejecuta una vez, en un prototipo desechable o en una porción de código estable que no se prevé modificar, aplicar los cinco principios de forma exhaustiva suele ser un exceso que añade complejidad sin beneficio real. De hecho, uno de los errores más frecuentes con SOLID es aplicarlo de manera dogmática, creando interfaces para todo, capas de abstracción que nunca tendrán una segunda implementación e indirecciones que hacen el código más difícil de seguir, lo que constituye una forma de sobreingeniería tan perjudicial como ignorar por completo los principios. La actitud recomendable es usar SOLID con criterio, preguntándose no si el código cumple los principios al pie de la letra, sino si es probable que necesite cambiar por una zona determinada y cuánto costaría ese cambio; donde el cambio es previsible, invertir en un buen diseño conforme a SOLID compensa, y donde no lo es, la simplicidad directa suele ser la mejor opción. Además, los principios pueden aplicarse de forma gradual y selectiva, reforzando el diseño en las partes del sistema que más lo necesitan y dejando sencillas las que no. En definitiva, conviene conocer bien SOLID para poder aplicarlo cuando aporta, entenderlo como una herramienta de juicio y no como una obligación universal, y equilibrar siempre el beneficio de un diseño flexible con el coste de la complejidad que introduce.
¿Por dónde empiezo a aplicar SOLID si nunca lo hice?
Si nunca aplicaste SOLID, lo más recomendable es empezar de forma gradual y por los principios que dan más beneficio con menos riesgo de sobreingeniería, en lugar de intentar aplicar los cinco a la vez en todo el código. Un buen punto de partida es el principio de responsabilidad única, porque es el más intuitivo y el que más ayuda a ordenar el código sin introducir apenas complejidad: consiste simplemente en detectar clases o funciones que hacen demasiadas cosas distintas y separarlas en piezas más pequeñas y cohesionadas, cada una centrada en un propósito. Practicar esto entrena la mirada para reconocer cuándo algo mezcla responsabilidades, que es una habilidad de base para el resto. A partir de ahí, conviene familiarizarse con la inversión de dependencias, porque tiene un impacto muy grande en la testabilidad y la flexibilidad, y se entiende bien en la práctica al aprender a depender de interfaces y a recibir las dependencias desde fuera en lugar de crearlas dentro; este principio se apoya además en la técnica de la inyección de dependencias, muy útil de dominar. El principio abierto cerrado se comprende mejor una vez que se ha visto código que crece a base de acumular condicionales, momento en el que se aprecia el valor de poder extender añadiendo clases nuevas. La sustitución de Liskov y la segregación de interfaces suelen entenderse con más naturalidad cuando ya se tiene soltura con la herencia y las interfaces, y ayudan a evitar jerarquías forzadas e interfaces sobrecargadas. Una forma muy eficaz de aprender es a través del refactor: tomar código propio que resulte difícil de cambiar o de probar, identificar qué principio se está violando y aplicarlo para mejorarlo, observando cómo mejora la situación; así los principios dejan de ser teoría abstracta y se vinculan a problemas concretos. También es muy útil apoyarse en la base de la programación orientada a objetos y en el estudio de los patrones de diseño, que muestran los principios en acción. Y, sobre todo, conviene aplicar SOLID con mesura desde el principio, entendiendo que la meta es un código más fácil de cambiar y no cumplir una lista, para no caer en el exceso contrario de abstraer todo innecesariamente.
Fuentes
Documentación oficial y material de la comunidad consultados para esta guía. Fecha de consulta: 28 de julio de 2026.
Aportes de la comunidad Underc0de
- Underc0de, foro. Sección Programación. Diseño y buenas prácticas.
- Underc0de, foro. Sección Desarrollo web. Arquitectura de aplicaciones.
Documentación oficial
- MDN. Programación orientada a objetos. Base conceptual de SOLID.
- Microsoft. Architectural principles. Principios de diseño, incluidos SOLID.
- Refactoring Guru. Design Patterns. Contexto de diseño orientado a objetos.