Princípios SOLID em C#: teoria e prática com exemplos de código

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
```html

Introdução: Por que SOLID é a base do código C# de qualidade



Desenvolver em C# no ecossistema .NET exige não apenas conhecimento de sintaxe, mas também a capacidade de projetar aplicações flexíveis, sustentáveis e testáveis. SOLID é a sigla para cinco princípios fundamentais de design orientado a objetos, formulados por Robert Martin. Eles ajudam os desenvolvedores a evitar dependências "rígidas", duplicação de código e problemas de escalabilidade.



Neste artigo, vamos analisar cada um dos cinco princípios SOLID aplicados ao C#: da teoria a exemplos reais de código. Você aprenderá como a refatoração com SOLID torna seu código mais limpo e a manutenção dos projetos mais simples.



1. Single Responsibility Principle (SRP) — Princípio da Responsabilidade Única



Teoria

Uma classe deve ter apenas um motivo para mudar. Em outras palavras, cada classe é responsável por exatamente uma funcionalidade ou lógica de negócio. Se uma classe faz demais, ela se torna difícil de testar, modificar e reutilizar.



Prática: violação do SRP

public class OrderProcessor{    public void ProcessOrder(Order order)    {        // 1. Validação do pedido        if (order.Total <= 0) throw new Exception("Invalid order");                // 2. Salvamento no banco de dados        using var db = new AppDbContext();        db.Orders.Add(order);        db.SaveChanges();                // 3. Envio de notificação por email        SmtpClient client = new SmtpClient();        client.Send("admin@shop.com", order.CustomerEmail, "Order confirmed", "Thank you!");    }}

Aqui, OrderProcessor viola o SRP: ele é responsável pela validação, operações com banco de dados e envio de email. Alterar a lógica de envio de notificações exigiria modificar esta mesma classe.



Refatoração com SRP

public class OrderValidator{    public bool Validate(Order order) => order.Total > 0;}

public class OrderRepository{ public void Save(Order order) { using var db = new AppDbContext(); db.Orders.Add(order); db.SaveChanges(); }}

public class EmailService{ public void SendConfirmation(string email) { SmtpClient client = new SmtpClient(); client.Send("admin@shop.com", email, "Order confirmed", "Thank you!"); }}

public class OrderProcessor{ private readonly OrderValidator _validator; private readonly OrderRepository _repository; private readonly EmailService _emailService;

public OrderProcessor(OrderValidator validator, OrderRepository repository, EmailService emailService) { _validator = validator; _repository = repository; _emailService = emailService; }

public void ProcessOrder(Order order) { if (!_validator.Validate(order)) throw new Exception("Invalid order"); _repository.Save(order); _emailService.SendConfirmation(order.CustomerEmail); }}

Agora cada classe tem uma única área de responsabilidade. Isso simplifica os testes e a modificação.



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. Ou seja, você deve ser capaz de adicionar novas funcionalidades sem alterar o código existente.



Prática: violação do OCP

public class ShapeDrawer{    public void DrawShape(object shape)    {        if (shape is Circle circle)            Console.WriteLine($"Drawing circle with radius {circle.Radius}");        else if (shape is Rectangle rect)            Console.WriteLine($"Drawing rectangle {rect.Width}x{rect.Height}");        // Ao adicionar um novo tipo de forma — é necessário modificar este método!    }}


Refatoração com OCP através de abstração

public abstract c
```                

Blogs

Book Recommendations