Uma dica simples para entender o princípio da responsabilidade única
Existe o seguinte ditado: “o papel aceita tudo”. Isso é quase totalmente adaptável para os conceitos de programação. Eu poderia dizer: “o código aceita quase tudo”. Linguagens de programação de escopo aberto possuem a característica de não restringir muito o que o programador pode fazer. Isso lhe dá a liberdade de escrever códigos dos mais diversificados, o que inclui escrever código ruim.
Para evitar que isso ocorra, existem vários padrões e princípios que podem ser seguidos para dar ao programador um trilho sobre o qual ele pode caminhar. Um dos conjuntos de princípios mais conhecidos é o SOLID. A sigla está em inglês e consiste de 5 princípios básicos:
- Single responsibility principle (princípio da responsabilidade única)
- Open/closed principle (princípio de aberto/fechado)
- Liskov substitution principle (princípio da substituição de Liskov)
- Interface segregation principle (princípio da segregação de interface)
- Dependency inversion principle (princípio da inversão de dependência.
Neste artigo falaremos sobre o primeiro deles e como atingi-lo de forma relativamente simples.
A definição mais básica deste princípio seria:
Uma classe deve ter um, e somente um, motivo para mudar.
Sim, o termo usado é “classe” mesmo. Este princípio não se aplica somente a funções. Se aplica também a classes. Mas neste artigo focarei mais em funções.
O princípio da responsabilidade única, portanto, indica que funções devem fazer uma coisa e somente uma. Aí você pode pensar: mas e quando eu preciso de mais coisas? Neste caso, uma função deve chamar outra função que faça esta outra coisa e somente ela. Entendeu o conceito? Cada função é um especialista e vários especialistas realizam atingem o objetivo trabalhando em conjunto.
A princípio isso pode parecer um pouco inalcançável, ainda mais naquele projeto legado que tá cheio de código velho e tralha pra todo lado. Mas mesmo nesses projetos é possível aplicar esse princípio sem maiores problemas.
Para isso tenho uma dica que pode ajudar bem. Alinhe seu pensamento para planejar seu código da seguinte forma:
- Preciso escrever um método que atinja o objetivo A
- Para atingir A, é necessário fazer B, C e D.
- Para atingir B, é necessário fazer E e F.
- Para atingir C, não é necessário nada extra.
- Para atingir D, é necessário fazer E e G.
- E daí por diante.
Explicando com um pouco mais de detalhes, cada letra maiúscula na lista acima representa uma função. A função A tem um objetivo que para ser atingido é necessário chamar outras 3 funções, cada uma com uma responsabilidade: resolver parte do problema de A.
Estas outras funções podem subdividir ainda mais o problema em partes cada vez menores e, quando algo sai do escopo de sua responsabilidade, chama a função responsável por esse outro pedaço do problema.
Os objetivos disso são manter o código curto, fácil de entender, com menos duplicações de código (trechos de códigos que fazem a mesma coisa) e facilitar o reuso de funções. Se você observar, no exemplo acima a função E é chamada tanto no passo 3 como 5, porque ela resolve parte do problema em ambos os casos.
Esse foi o primeiro artigo sobre boas práticas e princípios que ajudam a escrever códigos de qualidade.
Se você quiser se aprofundar mais nos princípios do SOLID, recomendo a leitura do artigo O que é SOLID: O guia completo para você entender os 5 princípios da POO.
Para um aprendizado mais profundo no conceito de código limpo, recomendo a leitura do livro “Clean Code”, de Robert C. Martin.
Até logo e bons códigos.