O Princípio da Responsabilidade Única (SRP) — Falando sobre S.O.L.I.D.

Allyx Cristiano
4 min readJun 27, 2018

--

Keep it simple

Olá galera, este é meu primeiro aqui no Medium, venho importando meus posts do antigo post da It Happens pois acredito que podemos ter debates mais calorosos e globais por aqui, para conhecer um pouco mais sobre o que eu faço visitem meu LinkedIn. Este post sobre SRP vem como evolução de um artigo postado em um blog pessoal que hoje já não existe mais, nada melhor do que começar postando por aqui sobre um tema que eu adoro discutir, que é o de boas práticas.

Antes de começarmos, é interessante comentar a respeito do que se trata o acrônimo SOLID. É de um conjunto de princípios de boas práticas de design de classes, tais princípios são base para implementações de muitas linguagens e tecnologias que usamos, por isto a importância ter o entendimento para se fazer a aplicação destes no software que você está construindo. Segue a lista:

SRP The Single Responsibility Principle (O Princípio da Responsabilidade única) Uma classe deve haver uma, e apenas uma, razão para mudar.

OCP The Open Closed Principle (O Princípio Aberto Fechado) Você deve ser capaz de estender o comportamento de classes, sem precisar modifica-lo.

LSP The Liskov Substitution Principle (O Princípio da Substituição de Liskov) Sub-classes devem poder ser substituídas por suas Super-classes

ISP The Interface Segregation Principle (O Princípio da Segregação de Interface) Construa interfaces que atendam em especifico a clientes, evite interfaces grandes e complexas

DIP The Dependency Inversion Principle (O Princípio da Inversão de Dependência) Programe para uma abstração e não para uma implementação

O primeiro princípio que falarei será o SRP, então, vamos lá.

Robert C. Martin traz em seu livro Código Limpo, Habilidades Práticas do Agile Software as seguintes citações:

Por mais bonita que uma casa seja, uma mesa desarrumada retira seu esplendor. Quem é fiel no pouco também é no muito.

Que as frases acima lhes sirvam de inspiração.

Definição:

Uma classe deve haver uma, e apenas uma, razão para mudar. (Tio Bob)

Primeiro exemplo:

Vamos seguir a seguinte linha de raciocínio, você deseja efetuar uma formatação de um atributo que armazena o CPF em uma classe chamada Identificação, o método formatarCpf() deveria retornar a string do CPF em questão formatada com pontos e seu traço. Veja o código abaixo:

public class Identificacao {
String cpf;
public String getCpf() {
return cpf;
}
public void setCpf(String cpf) {
this.cpf = cpf;
}
public String formatarCpf() {
String primeiraParte = getCpf().substring(0, 3);
String segundaParte = getCpf().substring(3, 6);
String terceiraParte = getCpf().substring(6, 9);
String quartaParte = getCpf().substring(9, 11);
String cpfFormatado = primeiraParte + "." + segundaParte + "." + terceiraParte + "-" + quartaParte;
setCpf(cpfFormatado);
return cpfFormatado;
}
}

E aí, o método faz o que é proposto? Sim, porém faz algo mais, além de formatar o CPF, o atributo que representa esta informação é alterado para o agora formatado com a chamada de setCpf(cpfFormatado) antes de efetuar o retorno, quem chamar este método vai querer apenas receber uma string de CPF formatada porém irá acabar por alterar o atributo CPF toda vez que chamar o método formatarCpf(), conseguem visualizar o problema? Este método não faz só uma coisa, este código está dependente e provavelmente ocasionaria algum problema adicional futuro ao induzir quem apenas quer uma formatação de um texto a alterar um atributo, sem saber.

Vamos ao segundo exemplo, este foi extraído da página 44 do livro Código Limpo:

public class UserValidator {
private Cryptographer;
public boolean checkPassword(String userName, String password)
{
User user = UserGateway.findByName(userName);
if (user != User.NULL)
{
String codedPhrase = user.getPhraseEncodedByPassword();
String phrase = cryptographer.decrypt(codedPhrase, password);
if ("Valid Password".equals(phrase))
{
Session.initialize();
return true;
}
}
return false;
}
}

A assinatura desta função deixa claro para quem a chamar que se trata de uma checagem de login e senha, irá verificar se para o usuário em questão a senha está válida. O problema desta função está no trecho Session.initialize(), quem chamar esta função com o intuito de autenticar um usuário simplesmente sempre estará iniciando uma nova sessão onde dados poderão ser perdidos, esta é mais uma dependência decorrente da não aplicação do SRP. Tal código irá gerar confusão e muitas vezes quem o usa passará a o chamar com algumas restrições, apenas quando garantir que quer além de autenticar o usuário e senha deseja também iniciar uma nova sessão, caso essa função por algum motivo não possa ser separada o ideal seria renomeá-la para checkPasswordAndInitializeSession, isto apesar de continuar quebrando nosso principio ao menos deixa claro o que o método de fato faz.

O SRP ajuda você a manter de uma melhor forma seus métodos, classes e consequentemente projeto, pois eles acabam por se tornar claros e pequenos o que facilita seu entendimento e reaproveitamento. Espero que este conteúdo tenha lhes passado a ideia de como devemos separar algumas de nossas implementações, espero que isto seja só o começo.

Este é o primeiro de 5 artigos sobre o SOLID, então, nos vemos em breve! 😀

Referências:

Livro: Código Limpo, Habilidades Práticas do Agile Software — Robert C. Martin

Artigo: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

--

--

Allyx Cristiano

Gosto de trabalhar com refatoração, padrões de projeto, testes e qualidade de software aplicados a projetos inovadores.