SRP – O Princípio da Responsabilidade Única

Segundo o próprio Robert C. Martin (Uncle Bob), o SRP (Single Responsibility Principle) é com certeza, de todos os 5 princípios SOLID, o menos compreendido. Sinto em ter que dizer isto, mas ele está certo.

Vamos só esclarecer algumas coisas:

O que v…


This content originally appeared on DEV Community and was authored by Thiago Souza (ZeroDois)

Segundo o próprio Robert C. Martin (Uncle Bob), o SRP (Single Responsibility Principle) é com certeza, de todos os 5 princípios SOLID, o menos compreendido. Sinto em ter que dizer isto, mas ele está certo.

Vamos só esclarecer algumas coisas:

  • O que vamos tratar aqui não é a minha opnião e sim um conteúdo baseado na definição que o próprio criador deste conjunto de princípios desejava passar como mensagem quando publicou o seu artigo.

  • Os exemplos de código apresentados neste artigo foram criados para fins didáticos e não refletem a realidade. Ao menos não deveriam. 👀

Definição

Sem mais delongas, vou agora te apresentar a frase que melhor define o Princípio da Responsabilidade Única:

"Um módulo deve ser responsável por um, e apenas um, ator."

Felca - Tá certo isso?

Sim, é isso mesmo! Ele define um módulo como um arquivo fonte e, dependendo da linguagem de programação, um módulo é apenas um conjunto coeso de funções e estrutura de dados. Em .NET, por exemplo, podemos entender a definição de módulo como uma Classe.

Mas fique tranquilo, caro leitor! Se não foi exatamente assim que te ensinaram, este artigo foi feito com muito carinho para que você possa compreender este princípio em sua essência.

Reaproveitamento de código

O reaproveitamento de código é realmente muito importante, desde que este reaproveitamento não gerando um acoplamento entre atores distintos.

Vamos imaginar um cenário hipótético (e muito simples) onde a classe Pedido possua dois métodos públicos utilizados por dois atores diferentes:

public class Pedido 
{
    public List<ItemPedido> Itens { get; set; }

    // Método utilizado pelo ator responsável pelo Faturamento
    public decimal CalcularImpostos(decimal percentualImposto)
    {
        decimal valorTotal = CalcularValorTotal();

        decimal imposto = valorTotal * percentualImposto;

        return imposto;
    }

    // Método utilizado pelo ator responsável pelas Vendas
    public decimal CalcularComissao(decimal percentualComissao)
    {
        decimal valorTotal = CalcularValorTotal();

        decimal comissao = valorTotal * percentualComissao;

        return comissao;
    }

    // Método privado compartilhado entre os métodos 
    // CalcularImpostos e CalcularComissao
    private decimal CalcularValorTotal()
    {
        decimal valorTotal = Itens.Sum(item => item.Valor);

        return valorTotal;
    }
}

Esta tentativa de reaproveitamento de código faz com que os atores de Faturamento e Vendas fiquem acoplados um ao outro. Qualquer alteração na função CalcularValorTotal atinge diretamente os dois atores.

Digamos que em algum momento futuro o ator de vendas decida que não quer mais considerar itens do tipo Camiseta para o pagamento de comissões. O desenvolvedor prontamente decide incluir um filtro antes de somar os itens no método CalcularValorTotal, sobe as alterações para o ambiente de homologação e pede para o ator de vendas validar a alteração antes de subir para produção.

O ator de vendas realiza todos os testes minuciosamente e indica que está tudo OK. O desenvolvedor todo animado faz o depoy no ambiente de produção.

Dias (ou semanas) depois, alguém descobre que essa alteração quebrou o cálculo de impostos gerando um enorme problema fiscal para a empresa.

Michael Scott frustrado

Isso por que nem fomos muito longe falando, por exemplo, sobre o processo de merge das branches de outros desenvolvedores da equipe.

Tenho certeza que você já consegue imaginar a criticidade e o motivo pelo qual devemos evitar que atores diferentes estejam acoplados uns aos outros.

Dependendo do seu tempo na área de desenvolvimento, me arrisco a dizer que, muito provavelmente você já tenha vivenciado algum tipo de situação como esta.

Mas o destino quis que você chegasse até este ponto da leitura e agora você tem o poder nas mãos de simplificar o processo de desenvolvimento de software para você e todos os seus colegas de trabalho, evitando o famoso "arruma de um lado e estraga do outro".

Solução

Existem várias formas de evitar (e solucionar) este problema. Pensando a longo prazo, na saúde do software e no seu emprego, esta poderia ser uma boa sugestão:

// Entidade de Pedido
public class Pedido 
{
    public List<ItemPedido> Itens { get; set; }
}

// Classe específica para o calculo de imposto de um pedido
// exclusiva para o ator responsável pelo Faturamento
public class ProvedorCalculoImpostoPedido(Pedido pedido)
{
    public decimal Calcular(decimal percentualImposto)
    {
        decimal totalImpostos = 0;

        List<PedidoItens> itens = pedido.Itens;

        foreach (var item in itens)
        {
            totalImpostos += item.Valor * percentualImposto;
        }

        return totalImpostos;
    }
}

// Classe específica para o cálculo de comissão de um pedido
// exclusiva para o ator responsável pelas Vendas
public class ProvedorCalculoComissaoPedido(Pedido pedido)
{
    public decimal Calcular(decimal percentualComissao)
    {
        decimal totalComissao = 0;

        List<PedidoItens> itens = pedido.Itens
            .Where(x => x.Tipo != TipoItemPedido.Camiseta);

        foreach (var item in itens)
        {
            totalComissao += item.Valor * percentualComissao;
        }

        return totalComissao;
    }
}

Qualquer nova solicitação de mudança nestes métodos, realizada por qualquer dos atores do sistema, não deverá mais gerar os problemas relatados anteriormente e as classes agora são responsáveis por um, e apenas um, ator. Lindo, não é mesmo?

Antes de ir embora, me conta aí: Antes de ler este artigo, você já dominava o SRP?

Obrigado pela sua atenção e espero que este artigo tenha sido útil para você.

Me siga para receber mais conteúdos como este. ♥️

Recomendação de leitura
Arquitetura Limpa - O Guia do Artesão para Estrutura e Design de Software
Robert Cecil Martin, 2019.


This content originally appeared on DEV Community and was authored by Thiago Souza (ZeroDois)


Print Share Comment Cite Upload Translate Updates
APA

Thiago Souza (ZeroDois) | Sciencx (2025-01-03T05:16:26+00:00) SRP – O Princípio da Responsabilidade Única. Retrieved from https://www.scien.cx/2025/01/03/srp-o-principio-da-responsabilidade-unica/

MLA
" » SRP – O Princípio da Responsabilidade Única." Thiago Souza (ZeroDois) | Sciencx - Friday January 3, 2025, https://www.scien.cx/2025/01/03/srp-o-principio-da-responsabilidade-unica/
HARVARD
Thiago Souza (ZeroDois) | Sciencx Friday January 3, 2025 » SRP – O Princípio da Responsabilidade Única., viewed ,<https://www.scien.cx/2025/01/03/srp-o-principio-da-responsabilidade-unica/>
VANCOUVER
Thiago Souza (ZeroDois) | Sciencx - » SRP – O Princípio da Responsabilidade Única. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/01/03/srp-o-principio-da-responsabilidade-unica/
CHICAGO
" » SRP – O Princípio da Responsabilidade Única." Thiago Souza (ZeroDois) | Sciencx - Accessed . https://www.scien.cx/2025/01/03/srp-o-principio-da-responsabilidade-unica/
IEEE
" » SRP – O Princípio da Responsabilidade Única." Thiago Souza (ZeroDois) | Sciencx [Online]. Available: https://www.scien.cx/2025/01/03/srp-o-principio-da-responsabilidade-unica/. [Accessed: ]
rf:citation
» SRP – O Princípio da Responsabilidade Única | Thiago Souza (ZeroDois) | Sciencx | https://www.scien.cx/2025/01/03/srp-o-principio-da-responsabilidade-unica/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.