Principios SOLID en C#: teoría y práctica de la A a la Z

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 a los principios SOLID en C#

\n

El desarrollo en C# dentro del ecosistema .NET requiere no solo conocimiento de sintaxis, sino también la capacidad de diseñar sistemas flexibles, mantenibles y comprobables. Para esto fueron creados los principios SOLID: cinco reglas fundamentales de la programación orientada a objetos, formuladas por Robert Martin (Tío Bob).

\n

El acrónimo SOLID se desglosa como:

\n
    \n
  • S — Single Responsibility Principle (Principio de responsabilidad única)
  • \n
  • O — Open/Closed Principle (Principio abierto/cerrado)
  • \n
  • L — Liskov Substitution Principle (Principio de sustitución de Liskov)
  • \n
  • I — Interface Segregation Principle (Principio de segregación de interfaces)
  • \n
  • D — Dependency Inversion Principle (Principio de inversión de dependencias)
  • \n
\n

En este artículo analizaremos cada principio en la práctica con ejemplos en C#, mostraremos cómo su violación genera problemas y cómo su correcta aplicación hace que el código sea más limpio.

\n\n

1. Principio de responsabilidad única (SRP)

\n

Esencia: Una clase debe tener solo una razón para cambiar. En otras palabras, cada clase es responsable de una tarea claramente definida.

\n\n

Violación de SRP en C#

\n

Consideremos un ejemplo típico: la clase OrderService, que hace demasiado:

\n
public class OrderService\n{\n    public void ProcessOrder(Order order)\n    {\n        // 1. Guardar en BD\n        SaveToDatabase(order);\n        \n        // 2. Enviar email\n        SendEmail(order.CustomerEmail, "Pedido realizado");\n        \n        // 3. Registrar en log\n        File.WriteAllText("log.txt", $"Pedido {order.Id} procesado");\n    }\n    \n    private void SaveToDatabase(Order order) { /* ... */ }\n    private void SendEmail(string email, string message) { /* ... */ }\n}
\n

Problema: Un cambio en la lógica de envío de email o en la forma de registrar en log provocará una modificación en la clase OrderService. Esto viola SRP.

\n\n

Implementación correcta de SRP

\n

Separamos las responsabilidades en servicios individuales:

\n
public class OrderProcessor\n{\n    private readonly IOrderRepository _repository;\n    private readonly INotificationService _notificationService;\n    private readonly ILogger _logger;\n    \n    public OrderProcessor(\n        IOrderRepository repository,\n        INotificationService notificationService,\n        ILogger logger)\n    {\n        _repository = repository;\n        _notificationService = notificationService;\n        _logger = logger;\n    }\n    \n    public void ProcessOrder(Order order)\n    {\n        _repository.Save(order);\n        _notificationService.SendConfirmation(order.CustomerEmail);\n        _logger.Log($"Pedido {order.Id} procesado");\n    }\n}\n\npublic interface IOrderRepository { void Save(Order order); }\npublic interface INotificationService { void SendConfirmation(string email); }\npublic interface ILogger { void Log(string message); }
\n

Ahora cada clase es responsable solo de su tarea. Un cambio en la lógica de registro no afecta el procesamiento de pedidos.

\n\n

2. Principio abierto/cerrado (OCP)

\n

Esencia: Las clases deben estar abiertas para extensión, pero cerradas para modificación. Es decir, debe poder agregar nuevo comportamiento sin cambiar el código existente.

\n\n

Violación de OCP en C#

\n

Ejemplo clásico: una calculadora con condicionales:

\n
public class AreaCalculator\n{\n    public double CalculateArea(object shape)\n    {\n        if (shape is Rectangle rect)\n            return rect.Width * rect.Height;\n        else if (shape is Circle circle)\n            return Math.PI * circle.Radius * circle.Radius;\n        // ¡Agregar una nueva figura requiere modificar este método!\n        throw new NotSupportedException();\n    }\n}                

Blogs

Book Recommendations