02 jun 2016

Operação Lava-Java! Nº 2 – Princípio da Responsabilidade Única

SRP – SINGLE RESPONSIBILITY PRINCIPLE

“Uma classe deveria ter apenas uma razão para ser modificada.”

A expressão “responsabilidade” nos remete a responsável – que, por sua vez, nos remete a algo ou alguém. Dentro do SRP, coisas que se modificam pelo mesmo motivo deveriam ficar juntas, assim como, coisas que se modificam por motivos diferentes deveriam ficar separadas. De acordo com o Uncle Bob, responsabilidade é a razão para uma classe ter que ser modificada. Você conseguirá distinguir melhor as responsabilidades de sua classe, ou estrutura similar, pensando no usuário ao qual a classe é destinada. Para facilitar a compreensão, vamos a um exemplo:

1
2
3
4
5
6
7
8
9
10
11
public class Carro {
     void abastecer();

     void trocarPneus();

     void pintar();

     Carro findById(Long id);

     void desamassar();
}

Nesta classe (CARRO), quantas responsabilidades você diria que ela possui? De acordo com a definição do SRP, ela possui quatro. Abastecer é uma responsabilidade e é função do posto de gasolina.Trocar pneus é responsabilidade do borracheiro. Pintar e desamassar podemos definir que é de responsabilidade do funileiro. E, por último, FindById podemos dizer que é responsabilidade do DBA. Claramente, esta classe possui responsabilidade demais e devemos separá-las. Entretanto, isto criaria muitas classes cujas teriam apenas um método ou talvez dois. Isso não é ruim?

Não, não existe problema algum em ter várias classes e muito menos elas terem que tenham poucos métodos, como disse foi dito no primeiro post da série. As classes deveriam ser coesas e aquele linguição estrutural não pertence ao Design Orientado a Objetos. Uma classe com mil métodos e responsabilidades é ruim de manter. Se mantivermos esses métodos na classe “carro” e tivéssemos as classes “caminhão”, “moto”, “ônibus”, elas provavelmente também conteriam a maioria destes métodos. Agora, imagine se o borracheiro que utiliza o sistema pedisse para você modificar a forma em que a troca de pneus é feita. Você teria que procurar todas as classes que implementam o método “trocar pneus” e modificar o comportamento delas. O fato de ter que modificar várias classes por causa de uma alteração significa que há um design mal elaborado neste sistema, com classes que não estão coesas e tornando-o rígido*. Uma das soluções para isto é abstrair a responsabilidade de trocar pneu destas classes e transferir para a classe “borracheiro”.

CTA-ebook-transformação-digital

Vale ressaltar que muitos desenvolvedores, ao ter um primeiro contato com o SRP, começam a abstrair códigos das classes devido à impressão de estarem duplicado em várias partes do sistema e, por não terem compreendido o conceito de responsabilidade, fazem isso de forma errada. Imagine que em um sistema de gestão empresarial temos o funcionário, o módulo de RH – que calcula os gastos do funcionário – e o módulo administrativo, que também calcula os gastos do funcionário. Por uma coincidência os dois métodos de cálculo são idênticos, o que remete ao pensamento de que estão duplicados. Então o desenvolvedor pensa: “vou abstrair e criar a classe ‘CalculadoraGastos’ para os dois módulos usarem”, mas sem lembrar que os usuários aos quais aqueles métodos eram destinados não são os mesmos. Eis que depois de uns dias a pessoa que cuida da parte administrativa da empresa pede para você modificar no módulo administrativo a forma como o cálculo de gastos é feita e adicionar os gastos do funcionário com luz, água e alimentação. O desenvolvedor vai até a abstração CalculadoraGastos e adiciona os gastos, mas sem lembrar que o RH também utiliza o mesmo método e não usa esses gastos adicionais no calculo, gerando bugs no cálculo de gastos do RH. Resumindo, o desenvolvedor não devia ter unificado os métodos porque são para usuários diferentes, ou seja: ele deixou aquele método com duas razões para ser alterado e causou uma fragilidade**, que também é sinônimo de um design mal elaborado, no sistema.

*Rigidez é a tendência de um sistema para resistir a mudanças por ter que realizá-las em vários lugares.
**Fragilidade é a tendência de modificar algo e quebrar uma parte do sistema em outro lugar.

Gabriel Suaki
About Gabriel Suaki

Software Engineer at redspark Gabriel Suaki - Software Engineer at redspark.

Leave a Comment