Principios SOLID en TypeScript: teoría y práctica con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: Por qué SOLID es importante en TypeScript



SOLID es un acrónimo de cinco principios fundamentales de diseño orientado a objetos, formulados por Robert Martin (Tío Bob). En el contexto de TypeScript, estos principios adquieren un valor especial gracias al sistema de tipos estricto y al soporte de paradigmas modernos de POO. La aplicación de SOLID hace que el código sea más flexible, comprobable y mantenible, lo cual es crítico para proyectos escalables.



En este artículo analizaremos cada principio SOLID con ejemplos prácticos en TypeScript, mostraremos antipatrones y sus implementaciones correctas. Aprenderá a escribir código que no se rompa al añadir nueva funcionalidad.



1. Single Responsibility Principle (SRP) — Principio de responsabilidad única



Teoría

Cada clase debe tener una única razón para cambiar. Esto significa que la clase debe encargarse solo de una parte de la funcionalidad del programa. Si una clase realiza varias tareas, es más difícil de mantener y probar.



Antipatrón (violación de SRP)

class UserService {    saveUser(user: User): void {        // Guardar en BD        console.log('User saved');    }

sendEmail(user: User, message: string): void { // Enviar email console.log(`Email sent to ${user.email}`); }

generateReport(user: User): string { // Generar informe return `Report for ${user.name}`; }}


Implementación correcta (SRP)

class UserRepository {    save(user: User): void {        // Solo guardar    }}

class EmailService { send(user: User, message: string): void { // Solo enviar email }}

class ReportGenerator { generate(user: User): string { // Solo generar informes }}


2. Open-Closed Principle (OCP) — Principio de abierto/cerrado



Teoría

Las clases deben estar abiertas para extensión, pero cerradas para modificación. La nueva funcionalidad debe añadirse mediante herencia o composición, no modificando el código existente.



Antipatrón (violación de OCP)

class PaymentProcessor {    processPayment(type: string, amount: number): void {        if (type === 'card') {            // Procesar tarjeta        } else if (type === 'paypal') {            // Procesar PayPal        } else if (type === 'crypto') {            // Procesar criptomoneda        }        // ¡Al añadir un nuevo tipo, hay que modificar la clase!    }}


Implementación correcta (OCP)

interface PaymentMethod {    process(amount: number): void;}

class CardPayment implements PaymentMethod { process(amount: number): void { console.log(`Processing card payment: $${amount}`); }}

class PayPalPayment implements PaymentMethod { process(amount: number): void { console.log(`Processing PayPal payment: $${amount}`); }}

class PaymentProcessor { constructor(private paymentMethod: PaymentMethod) {}

process(amount: number): void { this.paymentMethod.process(amount); }}


3. Liskov Substitution Principle (LSP) — Principio de sustitución de Barbara Liskov



Teoría

Los objetos de una clase base deben poder ser reemplazados por objetos de sus subclases sin alterar el funcionamiento del programa. Las subclases no deben cambiar el comportamiento esperado de la clase base.



Antipatrón (violación de LSP)

class Rectangle {    constructor(public width: number, public height: number) {}

setWidth(width: number): void { this.width = width; }

setHeight(height: number): void { this.height = height; }

getArea(): number { return this.width * this.height; }}

class Square extends Rectangle {

Blogs

Book Recommendations