SOLID, Você Tem Que Aplicar Agora!
O que é SOLID?
SOLID é um acrônimo de 5 princípios para se trabalhar com orientações a objetos, e são eles:
- Single Responsibility Principle
- Open Closed Principle
- Liskov Substitution Principle
- Interface Segragation Principle
- Dependency Inversion Principle
Antes de entrarmos no assunto propriamente dito, precisamos enteder alguns pricipios de orientações a objetos, e são eles:
- Coesão
- Encapsulamento
- Acoplamento
Coesão
Classes não coesas tendem a crescer indefinidamente, o que as tornam difíceis de manter.
- Uma classe coesa faz bem uma única coisa
- Classes coesas não devem ter várias responsabilidades
ENCAPSULAMENTO
Incluir ou proteger alguma coisa em uma capsula.
Classe não encapsuladas permitem violações de regras de negócio, além de aumentarem o acoplamento.
- Getters e setters não são formas eficientes de aplicar encapsulamento
- É interessante fornecer acesso apenas ao que é necessário em nossas classes
- O encapsulamento torna o uso das nossas classes mais fácil e intuitivo
ACOPLAMENTO
Acão de acoplar. Agrupamento aos pares.
Classe acopladas causam fragilidade no código da aplicação, o que dificulta sua manutenção
- Acoplamento é a dependência entre classes
- Acoplamento nem sempre é ruim, e que é impossível criar um sistema sem nenhum acoplamento
- Devemos controlar o nível de acoplamento na nossa aplicação
Esses principios nos ajudarão a entender um pouco sobre o SOLID e como aplica-lo, dito isto vamos entender sobre a primeira letra 'S' Single responsibility Principle.
Single Responsibility Principle
O autor do livro código limpo Robert (Uncle Bob) Martin escreveu a seguinte frase:
"Uma classe deveria ter apenas um único motivo para mudar."
E o que isso significa para nós?
Para entendermos melhor vamos a um exemplo:
public class Funcionario {
private String nome;
private String cpf;
private Cargo cargo;
private BigDecimal salario;
private LocalDate dataUltimoReajuste;
public Funcionario(String nome, String cpf, Cargo cargo, BigDecimal salario) {
this.nome = nome;
this.cpf = cpf;
this.cargo = cargo;
this.salario = salario;
}
public void reajustarSalario(BigDecimal aumento) {
BigDecimal percentualReajuste = aumento.divide(salario, RoundingMode.HALF_UP);
if (percentualReajuste.compareTo(new BigDecimal("0.4")) > 0) {
throw new ValidacaoException("Reajuste nao pode ser superior a 40% do salario!");
}
this.salario = this.salario.add(aumento);
this.dataUltimoReajuste = LocalDate.now();
}
}
Analise a classe funcionario, nela deveria apenas conter atributos da minha entidade, e não uma regra de reajustar salário, ou seja é uma regra de negócio que está dentro da minha entidade. Olhando para esse código pode-se perceber que não está coeso, além desta classe tratar de uma entidade, também está com a responsabilidade de calcular o reajuste do salário.
Vamos Corrigir!
Primeiro crie pacotes para cada funcionalidade, como exemplo a classe Funcionario ficará no package entities ou models, e a função de calcular o reajuste do salário ficará em um pacote services em uma nova classe chamada ReajusteService.
package br.com.robson.rh.services
import java.math.BigDecimal;
import java.math.RoundingMode;
import br.com.robson.rh.ValidacaoException;
import br.com.robson.rh.model.Funcionario;
public class ReajusteService {
public void reajustarSalarioDoFuncionario (Funcionario funcionario, BigDecimal aumento) {
BigDecimal salarioAtual = funcionario.getSalario();
BigDecimal percentualReajuste = aumento.divide(salarioAtual, RoundingMode.HALF_UP);
if (percentualReajuste.compareTo(new BigDecimal("0.4")) > 0) {
throw new ValidacaoException("Reajuste nao pode ser superior a 40% do salario!");
}
BigDecimal salarioReajustado = salarioAtual.add(aumento);
funcionario.atualizarSalario(salarioReajustado);
}
}
Agora quando precisar mudar alguma regra sobre reajuste, iremos diretamente na classe ReajusteService.
Mas será que só fazendo essas modificações meu código está pronto???
E a resposta é NÃO!
Siga meu perfil para companhar o próximo artigo onde vamos falar sobre o segundo Principio OPEN CLOSED.