Skip to content

Instantly share code, notes, and snippets.

@joffilyfe
Last active January 31, 2017 00:57
Show Gist options
  • Save joffilyfe/f6b2e82eaca4d76d5b744ee7efa7ce65 to your computer and use it in GitHub Desktop.
Save joffilyfe/f6b2e82eaca4d76d5b744ee7efa7ce65 to your computer and use it in GitHub Desktop.
O problema do calculo de salário
public enum Cargo {
DESENVOLVEDOR,
DBA,
TESTADOR;
}
public class CalculaSalario {
private Funcionario funcionario;
public CalculaSalario(Funcionario funcionario) {
this.funcionario = funcionario;
}
public double calcula(Funcionario funcionario) {
if (funcionario.getCargo().equals(Cargo.DESENVOLVEDOR)) {
if (funcionario.getSalario() > 3000) {
return funcionario.getSalario() * 0.80;
}
return funcionario.getSalario() * 0.90;
} else if (funcionario.getCargo().equals(Cargo.DBA)) {
if (funcionario.getSalario() > 2000) {
return funcionario.getSalario() * 0.90;
}
return funcionario.getSalario() * 0.85;
}
}
}
public class Funcionario {
private double salario;
public Funcionario() {
}
public double getSalario() {
return this.salario;
}
public void setSalario(double salario) {
this.salario = salario;
}
}

TDD e a Coesão

Ao testar o exemplo acima nós podemos perceber que a classe CalculaSalario pode crescer indefinidamente de acordo com o número de cargos e o número de regras que nós podemos implementar para cada tipo de cargo e valor de salário.

Nós temos dois problemas, o problema da complexibilidade exagerada (if aninhados) e de design. Nós percebemos que é preciso que haja um tipo de mudança para que possamos testar mais facilmente a classe CalculaSalario.

Refatorando

Podemos distribuir toda a regra de calculo de salário para classes diferentes, por exemplo o Desenvolvedor pode ter sua regra implementada por uma classe específica.

Criamos ento uma interface para garantir que quem quiser calcular a regra de salário use um método específico e criamos classes que implementam essa interface.

Ao criar um novo funcionário nós podemos passar qual é o tipo de regra que ele deverá seguir para mostrar o desconto no seu salário. Isto garante que a regra de calculo de salário possa ser alterada em tempo de execuçã

public interface RegraDeCalculo {
double calcula(Funcionario f);
}
/*
* Primeiro caso dos aninhados de Ifs
*/
public class DezPorCento implements DezOuVintePorCento {
public double calcula(Funcionario f) {
if (f.getSalario() > 3000) {
return f.getSalario() * 0.80;
}
return f.getSalario() * 0.90;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment