Comando Refatoração de trecho

4 respostas
J

Preciso refatorar o seguinte trecho de programa:

package programa;

public class Data {

private Integer day;

private Integer month;

private Integer year;

public Data(Integer day, Integer month, Integer year) {

    if (month < 1 && month > 12) {

        System.out.println("Informe um mes valido.");

    }

    if (day < 1 && day > 31) {

        System.out.println("Tem que ser de 1 a 31!!!");

    }

    if (year > 2020) {

        System.out.println("Ano invalido");

    }

    if (validarData(day, month, year)) {

        this.day = day;

        this.month = month;

        this.year = year;

    };

}

public boolean validarData(Integer dayV, Integer monthV, Integer yearV) {

    boolean diaCerto = false;

    if (monthV == 4 || monthV == 6 || monthV == 9 || monthV == 11) {

        if (dayV <= 30) {

            diaCerto = true;

        } else {

            diaCerto = false;

        }

    }

    if (monthV == 1 || monthV == 3 || monthV == 5 || monthV == 7 || monthV == 8 || monthV == 10 || monthV == 12) {

        if (dayV <= 31) {

            diaCerto = true;

        } else {

            diaCerto = false;

        }

    }

    if (month == 2) {

        if (yearV % 4 == 0) {

            if (day <= 29) {

                diaCerto = true;

            } else {

                diaCerto = false;

            }

        } else {

            if (day <= 28) {

                diaCerto = true;

            } else {

                diaCerto = false;

            }

        }

    }

    if (diaCerto) {

        return true;

    } else {

        return false;

    }

}

Fiz então as seguintes modificações:

===

package programa;

public class Data {

private Integer day, month, year;

public Data(Integer day, Integer month, Integer year) {

    if (month < 1 && month > 12) {

        System.out.println("Informe um mes valido.");

    }

    if (day < 1 && day > 31) {

        System.out.println("Tem que ser de 1 a 31!!!");

    }

    if (year > 2020) {

        System.out.println("Ano invalido");

    }

    if (validarData(day, month, year)) {

        this.day = day;

        this.month = month;

        this.year = year;

    }

}

public static boolean validarData(Integer dayV, Integer monthV, Integer yearV) {

        if (monthV == 4 || monthV == 6 || monthV == 9 || monthV == 11 && dayV <= 30) {

            diaCerto = true;

        }

        if (monthV == 1 || monthV == 3 || monthV == 5 || monthV == 7 || monthV == 8 || monthV == 10 || monthV == 12 && dayV <= 31) {

            diaCerto = true;
        }

        if (month == 2 && yearV % 4 == 0 && day <= 29) {

            diaCerto = true;

            if (month == 2 && yearV % 4 == 0 && day <= 28) {

                diaCerto = true;

            }

            return diaCerto;

        }

Gostaria de saber se ficou bom ou ainda posso fazer mais modificações? Se alguém tiver alguma sugestão, agradeceria.

4 Respostas

staroski

Ao invés de Integer utilize int.

J

Grato, Staroski, mas acha que há algum meio de simplificar os ifs.

staroski

A classe refatorada que você postou, nem compila… :frowning:

  • Eu usaria um switch pros meses.
  • O ano bissexto você só está verificando se é divisível por 4, está errado.
  • No caso de datas inválidas, você só está fazendo um println, o certo é lançar exceção pra nem deixar o objeto ser instanciado neste caso
  • Eu criaria atributos e parâmetros com nome em português, já que o nome da classe está em português
  • Eu implementaria um toString() pra facilitar a visualização de objetos do tipo Data
  • Eu implementaria os métodos hashCode e equals para permitir que dois objetos Data possam ser comparados
  • Eu implementaria a interface Comparable para permitir que objetos Data possam ser ordenados sem precisar de um Comparator

Classe refatorada:

public final class Data implements Comparable<Data> {

    public final int dia;
    public final int mes;
    public final int ano;

    public Data(int dia, int mes, int ano) {
        validaData(dia, mes, ano);
        this.dia = dia;
        this.mes = mes;
        this.ano = ano;
    }

    public static void validaData(int dia, int mes, int ano) {
        if (ano > 2020) {
            throw new IllegalArgumentException("Ano " + ano + " é inválido"); // não pode haver datas futuras?
        }
        if (mes < 1 && mes > 12) {
            throw new IllegalArgumentException("Mês " + mes + " é inválido");
        }
        boolean diaValido = dia >= 1;
        if (diaValido) {
            switch (mes) {
                case 2:
                    if ((ano % 400 == 0) || ((ano % 4 == 0) && (ano % 100 != 0))) { // é ano bissexto?
                        diaValido = dia <= 29;
                    } else {
                        diaValido = dia <= 28;
                    }
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    diaValido = dia <= 30;
                    break;
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    diaValido = dia <= 31;
                    break;
            }
        }
        if (!diaValido) {
            throw new IllegalArgumentException("Dia " + dia + " é inválido para o mês " + mes + " de " + ano);
        }
    }

    @Override
    public String toString() {
        return String.format("%02d/%02d/%04d", dia, mes, ano);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ano;
        result = prime * result + mes;
        result = prime * result + dia;
        return result;
    }

    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (object instanceof Data) {
            Data that = (Data) object;
            return this.ano == that.ano
                && this.mes == that.mes
                && this.dia == that.dia;
        }
        return false;
    }

    @Override
    public int compareTo(Data data) {
        int diferenca = this.ano - data.ano;
        if (diferenca == 0) {
            diferenca = this.mes - data.mes;
        }
        if (diferenca == 0) {
            diferenca = this.dia - data.dia;
        }
        return diferenca;
    }
}

Exemplo de uso:

import java.util.Arrays;

public class Exemplo {

    public static void main(String[] args) {
        Exemplo programa = new Exemplo();
        programa.executar();
    }

    public void executar() {
        Data data0 = new Data(30, 9, 2015);
        Data data1 = new Data(1, 8, 1997);
        Data data2 = new Data(1, 8, 1997);
        Data data3 = new Data(5, 2, 2003);

        System.out.println(data0 + " igual à " + data1 + ": " + data0.equals(data1));
        System.out.println(data0 + " igual à " + data2 + ": " + data0.equals(data2));
        System.out.println(data0 + " igual à " + data3 + ": " + data0.equals(data3));

        System.out.println(data1 + " igual à " + data2 + ": " + data1.equals(data2));
        System.out.println(data1 + " igual à " + data3 + ": " + data1.equals(data3));

        System.out.println(data2 + " igual à " + data3 + ": " + data2.equals(data3));

        Data[] datas = new Data[] { data0, data1, data2, data3 };
        System.out.println("Datas desordenadas: " + Arrays.toString(datas));

        Arrays.sort(datas);
        System.out.println("Datas ordenadas:    " + Arrays.toString(datas));

        try {
            Data anoInvalido = new Data(1, 1, 3001);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        try {
            Data mesInvalido = new Data(1, 13, 2010);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        try {
            Data diaInvalido = new Data(0, 3, 2017);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        try {
            Data diaValidoAnoBissexto = new Data(29, 2, 2020);
            System.out.println("ano bissexto: " + diaValidoAnoBissexto);

            Data diaInvalidoAnoBissexto = new Data(29, 2, 2019);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

Saída do programa:

30/09/2015 igual à 01/08/1997: false
30/09/2015 igual à 01/08/1997: false
30/09/2015 igual à 05/02/2003: false
01/08/1997 igual à 01/08/1997: true
01/08/1997 igual à 05/02/2003: false
01/08/1997 igual à 05/02/2003: false
Datas desordenadas: [30/09/2015, 01/08/1997, 01/08/1997, 05/02/2003]
Datas ordenadas:    [01/08/1997, 01/08/1997, 05/02/2003, 30/09/2015]
Ano 3001 é inválido
Dia 0 é inválido para o mês 3 de 2017
29/02/2020
Dia 29 é inválido para o mês 2 de 2019
J

O que eu preciso é modificar pouco aquele trecho de código dado e acrescentar um método para calcular idade, conforme já disse. Não tem como rodar em computador, pois não tem os outros módulos. A tarefa é eliminar duplicidades e if em excesso. Não preciso fazer todo o código. Na verdade, estou com dificuldades é em como introduzir o método de calcular idade.
Fiz um programa para testar, mas é diferente do exercício. Veja meu programa:
/*

  • To change this license header, choose License Headers in Project Properties.
  • To change this template file, choose Tools | Templates
  • and open the template in the editor.
    */
    package data2;
import java.time.LocalDate;

import java.time.Month;

import java.time.Period;

public class Data2 {

private Integer dia, mes, ano;

public Data2(Integer dia, Integer mes, Integer ano) {
        
                  
	this.dia = dia;
	this.mes = mes;
	this.ano = ano;
}

public boolean validarData() {
        
        boolean diaCerto=false;
        
        if(mes<1 || mes >12 ){
            
            System.out.println("Informe um mes valido.");

}
if(dia<1 || dia>31){

System.out.println("Tem que ser de 1 a 31!!!");

}
if(ano > 2020){

System.out.println("Ano invalido");

}

if (dia<32){
        
        switch (mes) {
            
            case 4:
            case 6:
            case 9:
            case 11:
        return diaCerto = dia <= 30;
        
                               
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
        return diaCerto = dia <= 31;

            default:
                
                if(ano %4 ==0){
                    
                    return diaCerto = dia<=29;

}else{

if(dia<=28){

return diaCerto = true;

}else{

return diaCerto = false;

}

}

}

}

return true;

}

public void calculoIdade() {
if(validarData()) {
                
                LocalDate l = LocalDate.of(ano, mes, dia); //specify year, month, date directly
                LocalDate now = LocalDate.now(); //gets localDate
                if(ano<=2020){
                Period diff = Period.between(l, now) ; //difference between the dates is calculated
                System.out.println("Idade: " + diff.getYears() + " anos, " + diff.getMonths() + " meses, " + diff.getDays() + " dias");
                }    
	}
	else {
                
                
		System.out.println("Quantidade de dias excede o total de dias do mês");
	
    
}
    }

public static void main(String[] args) {

	Data2 data2 = new Data2(7,10,1982);
	
	data2.calculoIdade();
}

}

Só que tenho de adaptar aquele trecho que enviei.

Criado 2 de julho de 2020
Ultima resposta 8 de jul. de 2020
Respostas 4
Participantes 2