Projeto 9 • Sistemas de Informação

Princípios SOLID

A História da Pizzaria da Ana: Construindo sistemas robustos que escalam de verdade.

🧱 SRP 🔓 OCP 🐦 LSP 🔌 ISP 💉 DIP
Prof. Afonso Brandão
🍕 A Crise na Pizzaria da Ana
Por que aplicar boas engenharias?

A Pizzaria da Ana começou simples: era pequena, um homem só e rápida. Mas o negócio cresceu e o "código espaguete" dominou a cozinha inteira:

Sintomas Clássicos do Caos

  • Rigidez: Adicionar borda recheada quebra o caixa da empresa.
  • Fragilidade: Mudar o sabor do mês derruba o app do motoboy.
  • Imobilidade: Impossível reaproveitar a receita no trailer de rua.
  • Viscosidade: Fazer uma "Gambiarra" de papel carbono dá muito menos trabalho.

O SOLID ajuda a reduzir o acoplamento explosivo e alinhar a coesão, definindo o que cada um faz na cozinha!

"Código limpo parece que foi escrito por alguém que se importa."
— Robert C. Martin (Uncle Bob)
SRP - Single Responsibility Principle
A Síndrome do Faz-Tudo da Pizzaria
S

"Uma classe deve ter um, e apenas um, motivo para mudar... Ou o Mário bate seu ponto e queima a pizza pra atender o telefone!"

❌ O Faz-Tudo da Cozinha (Multifuncional)
public class PizzariaSystem {
    public void AnotarPedidoTelefone() { /* .. */ }
    public void AmassarPizza() { /* .. */ }
    public void LigarMotoEntregar() { /* .. */ }
}

Se a moto quebrar (bug de delivery), toda a classe para. Ninguém assa mais nada.

✅ Funcionários Especialistas (Coeso)
public class AtendenteCaixa { ... }
public class PizzaioloMaster { ... }
public class DeliveryMotoboy { ... }

Se precisarmos trocar de iFood pra telefone de novo, o Pizzaiolo continua assando sem nem saber do reboliço.

OCP - Open/Closed Principle
Demolindo a Cozinha para Adicionar um Ovo Frito
O

"Seja Aberto para expansão (cardápio flexível), mas Fechado para modicações drásticas (quebrar paredes) na base do restaurante!"

❌ Ruim (Cozinha HardCoded)
if (pedido == "Calzone") PrepararCalzone();
else if (pedido == "Brotinho") PrepararBrotinho();
else if (pedido == "Esfiha") ...

// Ops, pediram Petisco? 
// Reescreve o FornosEngine.cs!
✅ Bom (Polimorfismo Abstrato)
public interface IPreparoCozinha { void Assar(); }

public class Calzone : IPreparoCozinha { ... }
public class Churros : IPreparoCozinha { ... }

// A Cozinha apenas comanda: 
// itemDeHoje.Assar(); 
// sem abrir o capô das receitas!
LSP - Liskov Substitution Principle
A Tragédia da Pizza de Sorvete Frita
L

"Se o sistema espera processar uma Pizza comum, injetar um herdeiro falso ou disfuncional fará tudo pegar fogo."

A regra: Subclasses herdadas (do tipo PizzaGourmet ➡️ Pizza) devem se comportar da forma que o pai prometeu à infraestrutura.

Exemplo: A Ana lança oficialmente a sua "Pizza de Picolé Assada".

❌ O ERRO DE HERANÇA FINGIDA (O Pinguim Voador)
public class Pizza { public virtual void AssarFornoA400Graus() { ... } }

public class PizzaDePicole : Pizza { 
    public override void AssarFornoA400Graus() {
        throw new Exception("MEU DEUS, ELA DERRETEU E QUEBROU O SISTEMA!"); 
    }
}
I - ISP - Interface Segregation Principle
O Entregador que é multado por não lavar louça
I

"Você não deve forçar as classes a dependerem (e implementarem) rotinas gordas que elas nunca vão usar."

❌ Contrato CLT Exagerado
public interface IFuncionarioPizzaria {
    void BaterMassaDeTrigo();
    void PilotarMotoDeEntrega();
}

public class Motoboy : IFuncionarioPizzaria {
    // Código inútil só pro C# parar de reclamar:
    public void BaterMassaDeTrigo() => return;
}
✅ Contratos Livres e Enxutos
public interface IAmassadeiro { void BaterMassa(); }
public interface IMotorista { void PilotarMoto(); }

// O Motoboy apenas herda de Motorista!
// A sanidade mental foi preservada!
DIP - Dependency Inversion Principle
Agarrados à Moto do João (A Inversão de Controle)
D

"A Pizzaria (Forte) não deveria quebrar ou parar porque o detalhe estrutural (João e a Moto) sofreu uma pausa."

❌ Se a moto dele furar, as vendas caem 100%
public class PizzariaAna {
    // Nós instanciamos a implementação crua! 😭
    private MotoboyJoao _mecanismo = new MotoboyJoao();
}

Pior: Teremos que jogar fora a classe se a Ana resolver usar Loggi amanhã de tarde.

✅ Abstração (Contratos e Plugs Genéricos)
public class PizzariaAna {
    private IServicoDeLogistica _rota;
    public PizzariaAna(IServicoDeLogistica entrega){
       _rota = entrega; // Recebeu a tomada pronta do C#!
    }
}

Passar iFood, Xbox ou Loggi via construtor agora é apenas plugar e rodar o negócio.

🛠️ Hands-on: A Cozinha da Sua Equipe

Missão: Auditoria e Refatoração no Seu Projeto

Feche o Figma, abra o seu Code e responda com honestidade: Ele está parecendo o cenário inicial do boteco da Ana?

  1. Identificar (SRP/ISP): Existe no back-end uma classe ou serviço que valida e-mail, liga pro banco e retorna HTML JSON esquisito ao mesmo tempo?
  2. Diagnosticar (OCP/DIP): Vocês usam cascatas de else ifs em vez de polimorfismo ou interfaces para variações dos dados?
  3. Operar: Escolha as engrenagens podres e tire esse atraso, aplicando limites justos e inversão de suas dependências hoje (Injeção via construtor)!
  4. Registrar: Use o README.md como livro caixa e conte qual peso tiramos do código base.
🚀 Ferramentas Médicas: Operando a Pizzaria

Ao realizar as refatorações dessa semana com seu grupo, invista tempo na fundação estrutural.

1. Extrair os Especialistas (A classe pai)

Tire a carga bruta do seu Service. Tudo que não for responsabilidade central daquele domínio, despache (ex: mande para um JwtAuthCore ou DataParserService).

2. Firmar Acordos (A interface padrão)

Desista do vínculo rígido do Classe -> Classe. Promova A abstração (Dependency Injection) usando containers de inversões do Spring, DotNet, NestJS.

                            // No container mestre de injeções da sua app!
                            builder.Services.AddScoped<ICompanhiaLogistica, LoggiService>();

                            // E na vida selvagem do controller...
                            public PizzariaController(ICompanhiaLogistica servicoDaVez){
                               // O framework injeta a dependência. ZERO acoplamento!
                            }