1. Introdução ao SOLID

SOLID é um acrônimo para cinco princípios de design de software orientados a objetos, introduzidos por Robert C. Martin (Uncle Bob). O objetivo principal é tornar o software mais fácil de entender, manter e estender ao longo do tempo.

S - SRP (Single Responsibility Principle): Uma classe deve ter apenas uma responsabilidade. Se ela lida com banco de dados e envio de e-mail, ela tem dois motivos para mudar.
O - OCP (Open/Closed Principle): Você deve ser capaz de adicionar novas funcionalidades sem alterar o código existente. Use interfaces e herança para estender o comportamento.
L - LSP (Liskov Substitution Principle): Se você tem uma classe base, qualquer classe que herde dela deve poder substituí-la sem que o sistema pare de funcionar.
I - ISP (Interface Segregation Principle): É melhor ter várias interfaces pequenas e específicas do que uma única interface "faz-tudo". Não force uma classe a implementar métodos que ela não usa.
D - DIP (Dependency Inversion Principle): Dependa de abstrações (interfaces), não de implementações concretas. Isso facilita a troca de componentes (ex: trocar SQL Server por MongoDB).

2. Atividade Prática: Auditoria de Código

Nesta atividade, você analisará o código do seu Dashboard (Projeto 9) para identificar onde os princípios SOLID podem ser aplicados para melhorar a qualidade arquitetural.

Passo 1: Identificação de "God Classes"

Procure por classes que tenham muitas linhas de código (geralmente Services ou Controllers). Verifique se elas realizam tarefas distintas, como: ler arquivos CSV, fazer cálculos matemáticos, salvar no banco e formatar strings.

Passo 2: Diagnóstico de Violações
  • A classe tem mais de um motivo para mudar? SRP
  • Você usa new ClasseConcreta() dentro de outra classe? DIP
  • Há muitos if/switch para decidir o comportamento baseado em um tipo? OCP
Passo 3: Refatoração Orientada

Escolha uma dessas violações e aplique a solução:

  • Para SRP: Crie uma nova classe para a responsabilidade extraída.
  • Para DIP: Crie uma interface e injete-a via construtor ou no Blazor usando @inject.

3. Exemplo de Refatoração no Blazor

Muitas vezes, colocamos toda a lógica de dados dentro do componente .razor. Veja como melhorar:

Antes (Acoplado):

// Dentro do Dashboard.razor
@code {
    protected override async Task OnInitializedAsync() {
        // Lógica de leitura de arquivo E processamento de dados AQUI
        var data = File.ReadAllLines("dados.csv"); 
    }
}

Depois (Seguindo SOLID):

// 1. Criar Interface
public interface IDashboardService { Task<List<Dados>> GetRelatorioAsync(); }

// 2. Criar Implementação
public class DashboardService : IDashboardService { ... }

// 3. No Blazor
@inject IDashboardService Service