além do script
Qualidade Software

SOLID ainda importa? Sim. E talvez mais do que nunca na era da IA.

Ferramentas de IA estão transformando a forma como desenvolvemos software. Hoje é possível gerar controllers, services, testes, queries SQL e até funcionalidades completas em poucos minutos.

arquiteturaqualidadesoftware

SOLID ainda importa? Sim. E talvez mais do que nunca na era da IA.

Ferramentas de IA estão transformando a forma como desenvolvemos software.

Hoje é possível gerar controllers, services, testes, queries SQL e até funcionalidades completas em poucos minutos.

Mas existe um problema:

Código rápido sem estrutura vira dívida técnica rápida.

A IA acelera a produção de código, mas não elimina a necessidade de uma arquitetura saudável.

Na prática, quanto mais código é gerado, mais importante se torna ter princípios que mantenham o projeto organizado, previsível e fácil de evoluir.

É exatamente nesse cenário que os princípios SOLID continuam extremamente relevantes.


Por que SOLID importa (ainda mais com IA)?

Quando um projeto segue SOLID:

  • O código é mais previsível.
  • As responsabilidades são claras.
  • As mudanças possuem impacto controlado.
  • Os testes são mais simples.
  • A revisão de código é mais rápida.
  • A própria IA gera sugestões melhores.

Quando o projeto não segue SOLID, a IA tende a amplificar os problemas existentes.

Ela pode até gerar a funcionalidade solicitada, mas normalmente seguirá os padrões já presentes no projeto.

Se a base estiver ruim, o resultado tende a ser ainda mais código difícil de manter.


Um exemplo fictício: o sistema da padaria

Imagine um sistema para uma rede de padarias. Existe uma classe chamada:

csharp
PedidoManager

Ela faz tudo:

  • Calcula descontos
  • Salva pedidos
  • Envia e-mails
  • Atualiza estoque
  • Gera relatórios
  • Emite notas fiscais

Um dia o time recebe uma solicitação simples:

"Adicionar um novo desconto para clientes VIP."

Parece uma tarefa de 30 minutos.

Mas ao alterar a lógica de desconto:

  • O relatório para de calcular corretamente.
  • O estoque deixa de atualizar.
  • A emissão da nota fiscal começa a falhar.

Por quê? Porque tudo está acoplado dentro da mesma classe.

Agora imagine outro cenário.

Um desenvolvedor precisa encontrar a funcionalidade de envio de e-mail. Naturalmente ele procura por:

text
Email
Notification
Mailer

Depois de uma hora procurando, descobre que a implementação está dentro de:

text
Financeiro/PedidoManager.cs

Misturada com cálculo de impostos.

Esse é exatamente o tipo de problema que SOLID ajuda a evitar.


Os 5 princípios em uma linha

S — Single Responsibility Principle

Uma classe, uma responsabilidade.

Se existem dois motivos para mudar uma classe, provavelmente ela deveria ser dividida.


O — Open Closed Principle

Estenda sem modificar.

Novo comportamento deve ser adicionado através de novas implementações, não alterando código que já funciona.


L — Liskov Substitution Principle

Uma subclasse deve poder substituir sua classe pai sem quebrar o sistema.

Se a implementação muda completamente o comportamento esperado, a herança está errada.


I — Interface Segregation Principle

Interfaces pequenas e específicas.

Ninguém deveria implementar métodos que não utiliza.


D — Dependency Inversion Principle

Dependa de abstrações.

A regra de negócio não deveria saber se os dados estão em SQL Server, PostgreSQL ou MongoDB.


Exemplos simples para memorizar

PrincípioExemplo
SUm robô serve bebidas. Outro limpa mesas.
ONovo tipo de bebida? Crie um novo robô sem alterar os existentes.
LQualquer robô garçom deve conseguir servir uma bebida sem comportamento inesperado.
IO robô que limpa não precisa implementar "ServirBebida()".
DO garçom não sabe onde a bebida é armazenada, apenas pede para alguém fornecer.

S — Single Responsibility Principle

❌ Ruim

csharp
public class UsuarioService
{
    public void SalvarUsuario()
    {
        // salva usuário
    }

    public void EnviarEmailBoasVindas()
    {
        // envia email
    }
}

A classe possui dois motivos para mudar:

  • Alteração de cadastro
  • Alteração de e-mail

✅ Bom

csharp
public class UsuarioService
{
    public void SalvarUsuario()
    {
        // salva usuário
    }
}

public class EmailService
{
    public void EnviarBoasVindas()
    {
        // envia email
    }
}

Cada classe possui apenas uma responsabilidade.


O — Open Closed Principle

❌ Ruim

csharp
public decimal CalcularDesconto(string tipoCliente)
{
    if (tipoCliente == "Normal")
        return 0;

    if (tipoCliente == "VIP")
        return 10;

    if (tipoCliente == "Premium")
        return 20;

    return 0;
}

Toda vez que surge um novo tipo de cliente a função precisa ser alterada.


✅ Bom

csharp
public interface IDesconto
{
    decimal Calcular();
}

public class DescontoVip : IDesconto
{
    public decimal Calcular() => 10;
}

public class DescontoPremium : IDesconto
{
    public decimal Calcular() => 20;
}

Novo desconto? Nova classe. Sem alterar o código existente.


L — Liskov Substitution Principle

❌ Ruim

csharp
public class Passaro
{
    public virtual void Voar()
    {
    }
}

public class Pinguim : Passaro
{
    public override void Voar()
    {
        throw new Exception("Pinguim não voa");
    }
}

Quem usa Passaro espera que ele voe. Mas o pinguim quebra essa expectativa.


✅ Bom

csharp
public abstract class Passaro
{
}

public interface IVoa
{
    void Voar();
}

public class Aguia : Passaro, IVoa
{
    public void Voar()
    {
    }
}

public class Pinguim : Passaro
{
}

Agora cada tipo possui apenas os comportamentos válidos.


I — Interface Segregation Principle

❌ Ruim

csharp
public interface IFuncionario
{
    void Trabalhar();
    void GerenciarEquipe();
}

Um estagiário não gerencia equipe. Mesmo assim é obrigado a implementar.


✅ Bom

csharp
public interface ITrabalhador
{
    void Trabalhar();
}

public interface IGerente
{
    void GerenciarEquipe();
}

Cada classe implementa apenas o que realmente utiliza.


D — Dependency Inversion Principle

❌ Ruim

csharp
public class PedidoService
{
    private readonly SqlServerRepository _repository =
        new SqlServerRepository();

    public void Salvar()
    {
        _repository.Salvar();
    }
}

A regra de negócio está presa ao SQL Server.


✅ Bom

csharp
public interface IRepository
{
    void Salvar();
}

public class SqlServerRepository : IRepository
{
    public void Salvar()
    {
    }
}

public class PedidoService
{
    private readonly IRepository _repository;

    public PedidoService(IRepository repository)
    {
        _repository = repository;
    }

    public void Salvar()
    {
        _repository.Salvar();
    }
}

Agora é possível trocar banco de dados sem alterar a regra de negócio.


O benefício menos falado: IA entende melhor projetos SOLID

Quando um projeto segue SOLID:

  • As responsabilidades são claras.
  • Os arquivos possuem objetivos bem definidos.
  • Os pontos de extensão são previsíveis.
  • Os testes são mais isolados.
  • As dependências são explícitas.

Isso não ajuda apenas os desenvolvedores.

Ajuda também as ferramentas de IA.

Um agente de IA consegue localizar mais facilmente onde uma alteração deve ser realizada quando a arquitetura é organizada.

Em projetos caóticos, a IA frequentemente replica problemas existentes, aumenta acoplamentos e cria mais dívida técnica.


Conclusão

SOLID nunca teve como objetivo tornar o código mais elegante. O objetivo sempre foi tornar mudanças mais seguras.

E isso se tornou ainda mais importante em uma era onde gerar código custa poucos segundos.

A velocidade de desenvolvimento aumentou. Mas a complexidade continua existindo.

Por isso, mais do que nunca:

Código gerado por IA sem SOLID é apenas uma forma mais rápida de criar problemas.

Já código estruturado com SOLID é mais fácil de entender, testar, revisar, evoluir e confiar.

E isso vale tanto para humanos quanto para as IAs que vão implementar a próxima feature.