Single Responsability Principle
Esse é o primeiro pilar do SOLID. A definição clássica é “Uma classse deve ter um, e apenas um motivo pra mudar.”.
Na prática, isso quer dizer que uma classe deve ser responsável por uma funcionalidade/parte específica do software. Em sistemas “blocos de cimentos”, é comum encontrarmos as chamadas “God Objects” (Objeto Deus), uma classe gigantesca que sabem e fazem tudo. O que contradiz o princípio da responsabilidade única.
Analogia
Imagine um funcionário de um restaurante que é, ao mesmo tempo, o cozinheiro, o garçom e o faxineiro . Se ele precisar mudar a forma como limpa o chão, o serviço de cozinha e o atendimento podem ser afetados ou interrompidos. No SRP, dividimos essas tarefas entre especialistas para que um não atrapalhe a evolução do outro.
Exemplo
Vamos imaginar um cenário em que o princípio não foi aplicado e após isso vamos transformá-lo em um código modular. Imagine um sistema que gerencia pedidos de e-commerce.
Exemplo Problema
Na classe Pedido abaixo, temos três motivos diferentes para serem alterados. Se a regra de calculo, banco e e-mail mudar. Cada método representa uma responsabilidade diferente para a classe Pedido
class Pedido:
def calcular_total(self):
# Lógica de negócio (Preço, impostos, descontos)
pass
def salvar_no_banco(self):
# Lógica de infraestrutura (Conexão SQL, tabelas)
pass
def enviar_email_confirmacao(self):
# Lógica de comunicação (Servidor SMTP, template do e-mail)
pass
Exemplo Solução
Para aplicar o SRP, separamos as tarefas em “especialistas”. Cada classe agora tem apenas uma razão para existir e mudar.
-
Pedidovai conter apenas a lógica de cálculocalcular_total -
salvar_no_bancovai ser uma nova classe chamadaPedidoRepository, que vai implementar o Padrão Repository -
enviar_email_confirmacaovai ser um serviço separado apenas por enviar comunicações
Desse modo, se você decidir trocar o e-mail por uma mensagem no WhatsApp, você altera apenas o serviço respectivo. A regra de cálculo do Pedido então permanece segura e intocada, como uma peça LEGO independente
Exemplo aplicado a contexto: Clean Architecture, Mediator, CQRS e DDD
Veja como o SRP se manifesta em um CommandHandler usando Mediator:
// Este Handler tem UMA única razão para mudar:
// Se o fluxo de "Criação de Pedido" for alterado.
public class CriarPedidoHandler : IRequestHandler<CriarPedidoCommand, Guid>
{
private readonly IPedidoRepository _repository; // Interface (DIP)
private readonly IMediator _mediator;
public async Task<Guid> Handle(CriarPedidoCommand request, CancellationToken ct)
{
// 1. Regra de Negócio (DDD: Entidade decide se pode ser criada)
var pedido = new Pedido(request.ClienteId, request.Itens);
// 2. Persistência (Clean Arch: O Handler não sabe se é SQL ou NoSQL)
await _repository.SalvarAsync(pedido);
// 3. Comunicação (Mediator: Dispara um evento para quem interessar)
// Isso separa a criação do pedido do envio de e-mail (SRP puro!)
await _mediator.Publish(new PedidoCriadoEvent(pedido.Id));
return pedido.Id;
}
Top comments (0)