Como eliminar código repetitivo? Programa de IMC

Pessoal, sou iniciante em Java e estou estudando os conceitos de orientação a objeto em Java. Pensando nisso, desenvolvi um programinha básico de cálculo de IMC em linha de comando, sempre procurando deixar o main o mais limpo possível (só chamando os métodos), sem construir nada ali. O programa tem apenas 2 classes e faz um teste de input do usuário, pra evitar que este digite valores inválidos.

A questão é que essa validação fica repetida, porque ele checa peso e depois checa altura, com código duplicado. Eu gostaria que vocês me dessem alguma sugestão pra eliminar a necessidade de ter esse código de validação duplicado. Eu deveria criar um método checaDados? Uma outra classe? Estou um pouco perdido.

Agradeço qualquer ajuda. Segue o código das duas classes:

package calculoIMC;
import java.util.Scanner;

public class IMC {
    
	//public static void main(String[] args) {

    private Scanner sc = new Scanner(System.in);
    private double peso, altura;
        
    void obterDados(){
    
    	System.out.println("Digite seu peso em quilos: ");
    		while (!sc.hasNextDouble()){ //enquanto input != double
    			System.out.println("Digite numeros apenas!");
    			sc.next(); //Faz o loop
    		}
    	peso = sc.nextDouble();
	
    	System.out.println("Digite sua altura: ");
    		while (!sc.hasNextDouble()){
    			System.out.println("Digite numeros apenas!");
    			sc.next();
    		}
		altura = sc.nextDouble();
    }

    void calcularIMC(){
    	
        final double formula = peso / (altura*altura);
        	if (formula < 17){
        		System.out.printf("Seu IMC: %.2f\n", formula); //usar PRINTF e "%.2f"
        		System.out.println("Muito abaixo do peso");
        	}
	        	else if ((formula > 17) && (formula < 18.49)){
	        		System.out.printf("Seu IMC: %.2f\n", formula);
	        		System.out.println("Abaixo do peso");
	        	}
	        	else if ((formula > 18.5 && formula < 24.99)){
	        		System.out.printf("Seu IMC: %.2f\n", formula);
	        		System.out.println("Peso normal");
	        	}
	        	else if ((formula > 25 && formula < 29.99)){
	        		System.out.printf("Seu IMC: %.2f\n", formula);
	        		System.out.println("Acima do peso");
	        	}
	        	else if ((formula > 30 && formula < 34.99)){
	        		System.out.printf("Seu IMC: %.2f\n", formula);
	        		System.out.println("Obesidade I");
	        	}
	        	else if ((formula > 35 && formula < 39.99)){
	        		System.out.printf("Seu IMC: %.2f\n", formula);
	        		System.out.println("Obesidade II (severa)");
	        	}
	        	else if (formula > 40){
	        		System.out.printf("Seu IMC: %.2f\n", formula);
	        		System.out.println("Obesidade III (morbida)");
	        	}
    }
}
package calculoIMC;

public class IMCTeste {

	public static void main(String[] args) {
		IMC corpo1 = new IMC();
		corpo1.obterDados();
		corpo1.calcularIMC();
	}
}
  1. Se o comando:
    System.out.printf("Seu IMC: %.2f\n", formula);

Então só é necessário dar esse comando uma única vez, antes do if. Coloque dentro do if somente o que for sujeito a condicional.

  1. Pense a respeito do comportamento do else. Se esse código aqui der false:
if (formula &lt; 17){  

Então, certamente, o valor de formula é >= 17. Portanto, não é necessário testar essa condição novamente no for do else.

Eu pensaria em um enum, algo assim:[code]public enum CategoriaPeso{

MUITO_ABAIXO(17.0, 18.49),
ABAIXO(18.5, 24.99);
//...

private double pesoInicial;
private double pesoFinal;

public static CategoriaPeso fromPeso(double){
    // implementacao
}

// resto do enum

}[/code]Fez sentido?

Agradeço aos colegas pela ajuda até aqui, mas, na verdade, minha preocupação com código repetido são aqueles dois blocos do while…

Notem que eu faço a mesma checagem, exibo a mesma mensagem. Imagino que deva ter uma forma de fazer aquilo apenas uma vez, seja por um método ou outra classe. Essa é minha dúvida principal e como eu poderia implementar essa solução, sempre levando em conta a POO.

Quanto aos if e else if, não vejo muito como escapar neste momento inicial de aprendizagem…

Fio, faz o que eu falei:

    void calcularIMC(){
        final double formula = peso / (altura*altura); 
        //Se está em todos os ifs, deveria estar fora do if.
        System.out.printf(&quot;Seu IMC: %.2f\n&quot;, formula);
        if (formula &lt; 17){
            System.out.println(&quot;Muito abaixo do peso&quot;);
        } else if (formula &lt; 18.49) {
            System.out.println(&quot;Abaixo do peso&quot;);
        } else if (formula &lt; 24.99){
            System.out.println(&quot;Peso normal&quot;);
        } else if (formula &lt; 29.99) {
            System.out.println(&quot;Acima do peso&quot;);
        } else if (formula &lt; 34.99) {
            System.out.println(&quot;Obesidade I&quot;);
        } else if (formula &lt; 39.99) {
            System.out.println(&quot;Obesidade II (severa)&quot;);
        } else {
            System.out.println(&quot;Obesidade III (morbida)&quot;);
        }
    }
}

Isso inclusive resolve um bug do seu programa: o que seu programa original imprime se o IMC for exatamente 25?

Beleza, Vini. Valeu pela resposta!

Tá aí um bug que eu realmente não tinha me atentado.