Princípios SOLID em C#: teoria e prática
SOLID é um acrônimo de cinco princípios fundamentais de programação orientada a objetos e design, formulados por Robert Martin (Uncle Bob). Esses princípios ajudam os desenvolvedores a criar código flexível, sustentável e escalável. Neste artigo, vamos analisar cada princípio SOLID em linguagem C# com exemplos de código específicos.
1. Single Responsibility Principle (SRP) — Princípio da Responsabilidade Única
Teoria: Cada classe deve ter apenas um motivo para ser alterada. Em outras palavras, a classe deve ser responsável por uma tarefa claramente definida.
Prática em C#: Vamos considerar um exemplo de violação do SRP e sua correção.
Violando o SRP:
public class OrderService{ public void CreateOrder(Order order) { // Lógica de criação do pedido Console.WriteLine("Pedido criado"); // Lógica de envio de email SendEmail("order@example.com", "Novo pedido"); // Lógica de registro File.WriteAllText("log.txt", "Pedido criado"); }}A classe OrderService é responsável por três tarefas diferentes: criação do pedido, envio de email e registro. Isso viola o SRP.
Correção respeitando o SRP:
public class OrderService{ private readonly IEmailService _emailService; private readonly ILogger _logger; public OrderService(IEmailService emailService, ILogger logger) { _emailService = emailService; _logger = logger; } public void CreateOrder(Order order) { // Lógica de criação do pedido Console.WriteLine("Pedido criado"); _emailService.SendEmail("order@example.com", "Novo pedido"); _logger.Log("Pedido criado"); }}
public interface IEmailService{ void SendEmail(string to, string message);}
public class EmailService : IEmailService{ public void SendEmail(string to, string message) { Console.WriteLine($"Email enviado para {to}"); }}
public interface ILogger{ void Log(string message);}
public class FileLogger : ILogger{ public void Log(string message) { File.WriteAllText("log.txt", message); }}Agora cada classe é responsável apenas pela sua tarefa: OrderService — pelo gerenciamento do pedido, EmailService — pelo envio de emails, FileLogger — pelo registro.
2. Open-Closed Principle (OCP) — Princípio Aberto/Fechado
Teoria: Entidades de software (classes, módulos, funções) devem estar abertas para extensão, mas fechadas para modificação.
Prática em C#: Usamos herança e interfaces para estender a funcionalidade sem alterar o código existente.
Violando o OCP:
public class PaymentProcessor{ public void ProcessPayment(string paymentType, decimal amount) { if (paymentType == "CreditCard") { // Processamento de cartão de crédito } else if (paymentType == "PayPal") { // Processamento do PayPal } // Adicionar um novo tipo requer alteração na classe }}Correção respeitando o OCP:
public interface IPaymentMethod{ void Process(decimal amount);}
public class CreditCardPayment : IPaymentMethod{ public void Process(decimal amount) { Console.WriteLine($"Processando cartão de crédito: {amount}"); }}
public class PayPalPayment : IPaymentMethod{ public void Process(decimal amount) { Console.WriteLine($"Processando PayPal: {amount}"); }}
public class PaymentProcessor{ public void ProcessPayment(IPaymentMethod paymentMethod, decimal amount) { paymen