Comando Refatoração de trecho

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.

Ao invés de Integer utilize int.

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

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

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.