Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Como eu uso o princípio do DRY ?

Como eu consigo aplicar o DRY no Java? Eu tentei inicializar a variável antes, mas não dá certo:


public class AliquotaImpostoRenda {

    public static void main(String[] args) {

        double salario = 3300.0;
        double imposto = 0;
        double aliquota = imposto * salario;
        String texto = "Sua aliquota é de: ";

        if (salario >= 1900.0 || salario <= 2800.0) {

            imposto = 7.5/100;
            System.out.println(texto + aliquota);

        } else if (salario >= 2800.01 || salario <= 3751.0) {

            imposto = 15.0/100;
            System.out.println(texto + aliquota);

        } else if (salario >= 3751.01 || salario <= 4664.0) {

            imposto = 22.5/100;
            System.out.println(texto + aliquota);
        }
    }

}

Porque aí a aliquota vai fazer o cálculo sem levar em consideração os ifs.

Sem inicializar nem compila o código.


public class AliquotaImpostoRenda {

    public static void main(String[] args) {

        double salario = 3300.0;
        double imposto;
        double aliquota = imposto * salario;
        String texto = "Sua aliquota é de: ";

        if (salario >= 1900.0 || salario <= 2800.0) {

            imposto = 7.5/100;
            System.out.println(texto + aliquota);

        } else if (salario >= 2800.01 || salario <= 3751.0) {

            imposto = 15.0/100;
            System.out.println(texto + aliquota);

        } else if (salario >= 3751.01 || salario <= 4664.0) {

            imposto = 22.5/100;
            System.out.println(texto + aliquota);
        }
    }

}

Porque diz que imposto pode não ter sido inicializado, quando ele claramente foi.

Eu sei que eu não estou muito a fundo na linguagem, mas... tem que ter alguma forma de fazer isso.

2 respostas
solução!

Oi Ana. Alguns pontos:

  1. Em Java existem tipos primitivos e variáveis de referência a objetos.

Nas linhas

double imposto = 0;
double aliquota = imposto * salario;

Estamos usando tipos primitivos. Eles não são referências a objetos na heap.

Por exemplo, você não pode atribuir "null" a uma váriavel de tipo primitivo, como double, ela só pode receber valores primitivos, não referências.

Então quando você altera o valor de imposto:

imposto = 7.5/100;
            System.out.println(texto + aliquota);

Ele não refletirá essa mudança em aliquota.

Observe (ou copie) o código abaixo:

        double imposto = 0;
        System.out.println("valor de imposto: " + imposto);
        double outroImposto = 5;
        System.out.println("valor de outro imposto: " + outroImposto);
        imposto = outroImposto;
        System.out.println("valor de imposto após 'referencia' a outro imposto: " + imposto);

        outroImposto ++;
        System.out.println("alteramos valor de outro imposto... ");
        System.out.println("novo valor de outro imposto: " + outroImposto);
        System.out.println("valor de imposto: " + imposto + "(não mudou)");

Este código vai gerar a seguinte saída:

valor de imposto: 0.0
valor de outro imposto: 5.0
valor de imposto após 'referencia' a outro imposto: 5.0
alteramos valor de outro imposto... 
novo valor de outro imposto: 6.0
valor de imposto: 5.0(não acompanhou a alteração)

Então primeiramente, quando você quer provocar modificações no valor de uma variável, ela deve ser uma variável de referência a um Objeto e não um tipo primitivo.

Porém se modificamos imposto e aliquota para Double

        Double imposto = null;
        Double aliquota = imposto * salario;

A linha aliquota irá gerar NullPointerException, pois imposto está nulo. Além disto, mesmo que o nullPointer fosse tratado, mudar o imposto ainda não iria refletir numa mudança em aliquota, pois a execução do código não retornará para "Double aliquota = imposto * salario;".

Ainda que aliquota seja uma variável de referência, quando executamos a linha

Double aliquota = imposto * salario;

Não estamos atribuindo em aliquota, uma referência a "multiplicação de imposto sobre salario" em qualquer momento, mas estamos pegando o resultado desta multiplicação naquele exato momento.

Aqui na verdade existirá um Autoboxing, ou seja o resultado da multiplicação, resultará em um valor que irá implicitamente criar um objeto e atribuir sua referência a aliquota. Já fugimos um pouco do foco da pergunta, eu acho, mas imagine que na verdade aquela sua mutiplicação de aliquota, faria implicitamente a mesma coisa que isto:

Double aliquota = new Double(imposto * salario);

Poderiamos resolver de várias formas, mas como você quer diminuir a repetição de código conforme o DRY, uma solução seria extrair este resultado para um novo método.

    public static void main(String[] args) {
        double salario = 3300.0;
        Double imposto = null;

        if (salario >= 1900.0 || salario <= 2800.0) {

            imposto = 7.5/100;
            calculaAliquota(salario, imposto);

        } else if (salario >= 2800.01 || salario <= 3751.0) {

            imposto = 15.0/100;
            calculaAliquota(salario, imposto);

        } else if (salario >= 3751.01 || salario <= 4664.0) {

            imposto = 22.5/100;
            calculaAliquota(salario, imposto);
        }
    }

    private static void calculaAliquota(double salario, Double imposto) {
        String texto = "Sua aliquota é de: ";
        Double aliquota = imposto * salario;
        System.out.println(texto + aliquota);
    }

Faça os testes você mesma, agora incluindo o valor de dedução :)

Abraço

Poxa, muitíssimo obrigada, Rodrigo e eu aqui achando que Java era simplesmente uma linguagem "bobona" que adorava debochar da minha cara. É só um "pouco" (muito, na verdade) diferente do que eu tô acostumada.

Não, não fugiu de forma nenhuma da pergunta! Quanto mais informação melhor!! De novo, muito obrigada :).