Object-Oriented Programming (OOP) and SOLID Principles: Encapsulation, Inheritance, Polymorphism, and Clean Architecture
Technical guide to OOP and clean architecture: the 4 pillars, coupling vs cohesion, dependency injection, and SOLID principles.
AS
AS
Aros Student
Aug 16, 20264 min890 views
Share:
Programación Orientada a Objetos (POO) y Principios SOLID: Código mantenible y escalable
Clases, Objetos, los 4 Pilares Fundamentales y el Estándar de Diseño SOLID
La Programación Orientada a Objetos (POO) es el paradigma de desarrollo más extendido en la industria del software corporativo. Se basa en organizar el código modelando entidades del mundo real como Clases (plantillas o planos estructurales) y Objetos (instancias concretas con estado y comportamiento propio). Sin embargo, programar con clases sin una metodología rigurosa suele conducir a "código espagueti". Para evitarlo, los Principios SOLID formulados por Robert C. Martin (Uncle Bob) establecen las reglas maestras para construir software modular, testeable y fácilmente extensible.
En la Tecnología Real (Explicación Sencilla)
En la Tecnología Real (Explicación Sencilla): Piensa en la construcción de un automóvil: - Clase vs Objeto: El plano de diseño de la fábrica es la Clase Auto. Cada vehículo físico que sale de la línea de ensamblaje con su propio color y matrícula es un Objeto. - Encapsulamiento: No necesitas saber cuántos voltios pasan por la bujía para conducir; solo presionas el pedal del acelerador (Interfaz pública segura). - Polimorfismo: Puedes presionar el acelerador en un auto a gasolina, en un auto eléctrico o en un camión; todos aceleran a su manera, pero tú usas el mismo pedal. - Principio Open/Closed (O en SOLID): Si quieres agregarle un portaequipaje en el techo al auto, no cortas el chasis con soplete; colocas un accesorio diseñado para acoplarse sin alterar el auto base.
Explicación Técnica Profunda
WIKIHOW STEP
Los 4 Pilares de la POO:
1.
Abstracción: Ocultar la complejidad interna y exponer únicamente las operaciones esenciales mediante contratos o interfaces.
2.
Encapsulamiento: Proteger el estado interno de un objeto restringiendo el acceso directo a sus atributos mediante visibilidad (private, protected, public) y métodos getters/setters.
3.
Herencia: Mecanismo donde una clase hija adquiere propiedades y métodos de una clase padre, promoviendo la reutilización de código.
4.
Polimorfismo: Capacidad de diferentes clases derivadas de responder al mismo mensaje o método con comportamientos específicos según su tipo.
WIKIHOW STEP
El Acrónimo SOLID:
S - Single Responsibility Principle (SRP): Una clase debe tener una única razón para cambiar (una sola responsabilidad).
O - Open/Closed Principle (OCP): Las entidades de software deben estar abiertas a la extensión, pero cerradas a la modificación.
L - Liskov Substitution Principle (LSP): Una subclase debe poder sustituir a su clase base sin alterar el correcto funcionamiento del programa.
I - Interface Segregation Principle (ISP): Los clientes no deben estar obligados a depender de interfaces o métodos que no utilizan.
D - Dependency Inversion Principle (DIP): Los módulos de alto nivel no deben depender de módulos de bajo nivel; ambos deben depender de abstracciones (Inyección de Dependencias).
Principio SOLID
Problema que Resuelve
Síntoma de Violación
Solución de Diseño
SRP
Clases "Dios" monstruosas
Una clase calcula nóminas, conecta a MySQL y envía emails
Separar en PayrollCalculator, UserRepository y EmailService
OCP
Modificar código viejo con riesgo de romperlo
Usar cadenas interminables de if/else o switch para nuevos tipos
Usar polimorfismo y clases derivadas o patrones Strategy
LSP
Excepciones inesperadas en subclases
Una clase Pinguino que hereda de Ave lanza error en volar()
Reestructurar la jerarquía con interfaces como IAveVoladora
ISP
Métodos vacíos o no implementados
Implementar una interfaz gigante de 30 métodos cuando solo usas 2
Dividir en múltiples interfaces pequeñas y cohesivas
DIP
Acoplamiento rígido a librerías concretas
Instanciar new MySQLDatabase() directo en el controlador
Inyectar una interfaz IDatabaseConnection en el constructor
arostik@ubuntu:~ (typescript)
// Ejemplo de Inversión de Dependencias (DIP) y Responsabilidad Única (SRP) en TypeScriptinterface INotificationSender { send(recipient: string, message: string): Promise<boolean>;}class EmailService implements INotificationSender { async send(recipient: string, message: string): Promise<boolean> { console.log(`Enviando email a ${recipient}: ${message}`); return true; }}class OrderProcessor { // Recibe la abstracción mediante Inyección de Dependencias (DIP) constructor(private notifier: INotificationSender) {} public processOrder(orderId: string, customerEmail: string): void { console.log(`Procesando orden #${orderId}...`); this.notifier.send(customerEmail, "Tu orden ha sido procesada con éxito."); }}
Nota Técnica
Nota Técnica sobre Composición sobre Herencia: Una de las advertencias más importantes en la ingeniería de software moderna es "Prefiere Composición antes que Herencia" (Composition over Inheritance). El uso excesivo de árboles de herencia profundos crea jerarquías rígidas y frágiles (Fragile Base Class Problem). Ensamblar objetos mediante componentes e interfaces pequeñas resulta en sistemas mucho más flexibles y fáciles de probar con mocks.
Buenas Prácticas y Advertencias de Errores Comunes
Evitar Getters y Setters indiscriminados: No hagas públicos todos los atributos con setters automáticos; mantén el estado inmutable o modifícalo exclusivamente a través de métodos de negocio con validaciones.
Inyección de Dependencias: Nunca instancies servicios externos (como clientes HTTP o conexiones SQL) con new dentro de la lógica central; pásalos a través del constructor.
Escribir Pruebas Unitarias Aisladas: El diseño desacoplado de SOLID te permite reemplazar componentes reales por Mocks o Stubs en tus tests unitarios en milisegundos.
Glosario Rápido
1.
Cohesión: Grado en el que todos los métodos y atributos de una misma clase están íntimamente relacionados con un único propósito funcional.
2.
Acoplamiento: Nivel de interdependencia entre dos módulos; el software de alta calidad busca siempre Bajo Acoplamiento y Alta Cohesión.
3.
Inyección de Dependencias (DI): Patrón de diseño donde los objetos reciben sus dependencias desde el exterior en lugar de crearlas ellos mismos internamente.
Mini Cuestionario Interactivo3 preguntas
Selecciona una opción para autoevaluarte al instante. La respuesta se califica de inmediato.
Aciertos: 0 / 3
1
¿Qué establece el Principio de Responsabilidad Única (Single Responsibility Principle)?
2
¿Qué pilar de la POO permite que objetos de diferentes clases respondan a la misma llamada de método con comportamientos específicos?
3
¿Por qué se recomienda favorecer la Composición antes que la Herencia profunda?
Diagnóstico y Práctica en Arostik
Valida y estructura payloads de objetos JSON y esquemas de configuración con nuestro Formateador y Validador JSON.