Como eliminar código repetitivo? Programa de IMC

5 respostas
michel79

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();
	}
}

5 Respostas

ViniGodoy
  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.

Rodrigo_Sasaki
Eu pensaria em um enum, algo assim:
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

}
Fez sentido?
michel79

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…

ViniGodoy

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("Seu IMC: %.2f\n", formula);
        if (formula &lt; 17){
            System.out.println("Muito abaixo do peso");
        } else if (formula &lt; 18.49) {
            System.out.println("Abaixo do peso");
        } else if (formula &lt; 24.99){
            System.out.println("Peso normal");
        } else if (formula &lt; 29.99) {
            System.out.println("Acima do peso");
        } else if (formula &lt; 34.99) {
            System.out.println("Obesidade I");
        } else if (formula &lt; 39.99) {
            System.out.println("Obesidade II (severa)");
        } else {
            System.out.println("Obesidade III (morbida)");
        }
    }
}

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

michel79

Beleza, Vini. Valeu pela resposta!

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

Criado 1 de novembro de 2013
Ultima resposta 4 de nov. de 2013
Respostas 5
Participantes 3