Autor Tema: Evitar excesivo anidamiento de instrucciones en Java, mejor diseño. (CU00662B)  (Leído 7358 veces)

Pasandav

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 39
    • Ver Perfil
Algo me dice..... que me complico la vida!!!  :o. jeje.

Me gustaría saber vuestra opinión. Gracias, otra vez.

Código: [Seleccionar]
import java.util.Scanner;
/**
 * Write a description of class comparaLetras here.
 *
 * @author (David Martínez)
 * @version (a version number or a date)
 */
public class comparaLetras
{
    public  static void main (String [] args)
    {
        Scanner text = new Scanner (System.in); // Puntero al objeto Scanner
        System.out.println("Escribe la palabra1: ");
        String palabra1 = text.nextLine();      // Creamos objeto Scanner que almacena primer valor
        System.out.println("Escribe la palabra2: ");
        String palabra2= text.nextLine();       // Creamos objeto Scanner que almacena segundo valor
        int a=0;                                // Variable int para los bucles While.
        boolean iguales=false;                  // Variable booleana para almacenar si son iguales o no.
       
        /*Si la longitud de "palabra1" es mayor que la de "palabra2". Recorreremos la "palabra2" hasta que se acaben sus letras en el prime bucle While
         * Si la letra almacenada en posición (a) de "palabra2" equals que letra almacenada en posición (a) de "palabra1"
         * Se le da valor "True" a la variable "iguales" y se muestra el mensaje de que son iguales.
         * Si la letra almacenada en posición (a) de "palabra2" es diferente que letra almacenada en posición (a) de "palabra1"
         * Se le da valor "False" a la variable "iguales" y se muestra el mensaje de que son diferentes.
         */
        if (palabra1.length() >= palabra2.length())
        {
            while (  a < palabra2.length())
            {
                if (palabra2.substring(a,a+1).equals(palabra1.substring(a,a+1)))
                {
                    iguales = true;
                    System.out.println("Letra " + (a+1) + " de \"Palabra1\" es (" + palabra1.toUpperCase().substring(a,a+1)+") = letra " + (a+1) + " de \"Palabra2\" es (" + palabra2.toUpperCase().substring(a,a+1) +") --->" + iguales);
                }
                else                                                                // Si la letra almacenada en posición (a) de "palabra2" es diferente que letra almacenada en posición (a) de "palabra1"
                {
                    iguales = false;
                    System.out.println("Letra " + (a+1) + " de \"Palabra1\" es (" + palabra1.toUpperCase().substring(a,a+1)+") <> letra " + (a+1) + " de \"Palabra2\" es (" + palabra2.toUpperCase().substring(a,a+1) +") --->" + iguales);
                }
                a= a + 1;
            }
            /*Cuando la variable a, llega a  la longitud de "palabra2" comienza otro bucle While que se ejecuta hasta recorrer la longitud "palabra1"
             * Al haber terminado con todos los caracteres de "palabra2", el valor de la variable "iguales" sera "false".
             * Muestra las letras que faltan del "palabra1" y el valor de "iguales".
             */
           
            while ( a < palabra1.length())
            {
                iguales = false;
                System.out.println("Letra " + (a+1) + " de \"Palabra1\" es (" + palabra1.toUpperCase().substring(a,a+1)+") <> letra " + (a+1) + " de \"Palabra2\" es ( ) --->" + iguales); 
                a= a + 1;
            }
        }
            //Si la longitud de "palabra1" NO es mayor que la de "palabra2". Recorreremos la longitud de "palabra1" hasta que se acaben sus letras en el prime bucle While.
        else
        {
            while (  a < palabra1.length())
            {
                if (palabra1.substring(a,a+1).equals(palabra2.substring(a,a+1)))
                {
                    iguales = true;
                    System.out.println("Letra " + (a+1) + " de \"Palabra1\" es (" + palabra1.toUpperCase().substring(a,a+1)+") = letra " + (a+1) + " de \"Palabra2\" es (" + palabra2.toUpperCase().substring(a,a+1) +") --->" + iguales); 
                }
                else
                {
                    iguales = false;
                    System.out.println("Letra " + (a+1) + " de \"Palabra1\" es (" + palabra1.toUpperCase().substring(a,a+1)+") <> letra " + (a+1) + " de \"Palabra2\" es (" + palabra2.toUpperCase().substring(a,a+1) +") --->" + iguales); 
                }
                a= a + 1;
            }
            while ( a < palabra2.length())
            {
                iguales = false;
                System.out.println("Letra " + (a+1) + " de \"Palabra1\" es ( ) <> letra " + (a+1) + " de \"Palabra2\" es (" + palabra2.toUpperCase().substring(a,a+1) +") --->" + iguales);
                a= a + 1;
            }
        }
    }
}

« Última modificación: 22 de Octubre 2015, 09:53 por Alex Rodríguez »

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:Evitar excesivo anidamiento de instrucciones en Java. (CU00662B)
« Respuesta #1 en: 14 de Octubre 2015, 13:22 »
Hola, aunque tu código funciona bien como tú mismo dices te has complicado. El diseño es más complicado de lo necesario y dentro de un if tienes un while y dentro del while otro if etc. esto no es adecuado excepto cuando es estrictamente necesario.

Recomendación 1: leer https://www.aprenderaprogramar.com/foros/index.php?topic=2327

Recomendación 2: ver cómo se resuelve de forma más sencilla e intentar resolverlo por tí mismo de forma similar (https://www.aprenderaprogramar.com/foros/index.php?topic=2089)

Saludos

Pasandav

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 39
    • Ver Perfil
Re:Evitar excesivo anidamiento de instrucciones en Java. (CU00662B)
« Respuesta #2 en: 15 de Octubre 2015, 23:27 »
Gracias por la respuesta.
Sigo intentandolo. ;D

Pasandav

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 39
    • Ver Perfil
Re:Evitar excesivo anidamiento de instrucciones en Java. (CU00662B)
« Respuesta #3 en: 16 de Octubre 2015, 00:46 »
Me he fijado en los ejemplos y (creo) que he podido comprender un poco más con respecto a la creación de objetos, métodos y funciones.

Me gustaría saber si es factible crear objetos para "casi" todo, como en mi ejemplo. No tengo claro aún si esto consume más recursos o menos.

Prometo poner comentarios en todo el ejemplo, pero no tengo demasiado tiempo para todo.

Aquí el Main:
Código: [Seleccionar]
/**
 * @author (David Martínez)
 * @version (a version number or a date)
 */
public class comparadorDeLetras
{
    public  static void main (String [] args)
    {
        muestraEnPantalla.pidePalabra (1);
        String palabra1 = registra_Teclado.introducePalabra();

        muestraEnPantalla.pidePalabra (2);
        String palabra2 = registra_Teclado.introducePalabra();
       
        int masLarga = Compara.palabraLarga(palabra1,palabra2); // Asigna el valor recibido al entero masLarga.
        int masCorta = Compara.palabraCorta(palabra1,palabra2); // Asigna el valor recibido al entero masCorta.
       
        muestraEnPantalla.palabraMasLarga (masLarga);
        muestraEnPantalla.palabraMasCorta (masCorta);

        int recorrePalabra=0;
        boolean esIgual=false;
        String letra1="";
        String letra2="";
       
        while (recorrePalabra < masCorta){
            letra1 = palabra1.substring(recorrePalabra,recorrePalabra+1);
            letra2 = palabra2.substring(recorrePalabra,recorrePalabra+1);
           
            esIgual = Compara.igualdad(letra1,letra2);
            muestraEnPantalla.igualdad(esIgual,recorrePalabra,letra1,letra2);
            recorrePalabra = recorrePalabra + 1;
        }
         
        while (recorrePalabra < masLarga)
        {
            if (palabra1.length() == masCorta)
            {
                letra2 = palabra2.substring(recorrePalabra,recorrePalabra+1);
                letra1 = "";
            }
            else
            {
                letra1 = palabra1.substring(recorrePalabra,recorrePalabra+1);
                letra2 = "";
            }
            esIgual = Compara.igualdad(letra1,letra2);
            muestraEnPantalla.igualdad(esIgual,recorrePalabra,letra1,letra2);
            recorrePalabra = recorrePalabra + 1;
        }
    }
}

Una clase solo para leer el teclado:
Código: [Seleccionar]
import java.util.Scanner;
/**
 * Write a description of class registra_Teclado here.
 *
 * @author (David Martinez)
 * @version (a version number or a date)
 */
public class registra_Teclado
{
    public registra_Teclado()
    {
    }

    static String introducePalabra()
    {
         Scanner palabra = new Scanner (System.in);
         String objPalabra = palabra.nextLine();
         return objPalabra;
    }
}

Otra para visualizar los datos en pantalla:
Código: [Seleccionar]
/**
 * @author (David Martinez)
 * @version (a version number or a date)
 */
public class muestraEnPantalla
{
    public muestraEnPantalla()
    { 
    }
   
    static void pidePalabra(int y)
    {
        System.out.println("Introduce la " + y + "ª. palabra.");
    }
   
    static void palabraMasLarga (int letras)
    {
        System.out.println("La palabra mas larga tiene " + letras + " letras.");
    }
   
    static void palabraMasCorta (int letras)
    {
        System.out.println("La palabra mas corta tiene " + letras + " letras.");
    }
   
    static void igualdad (boolean iguales,int recorrido, String letra1,String letra2)
    {
       if (iguales == false && letra1==""){ System.out.println("La palabra1 no tiene letra " + (recorrido + 1));}
       else if (iguales == false && letra2==""){ System.out.println("La palabra2 no tiene letra " + (recorrido + 1)); } 
       else {System.out.println("Letra " + (recorrido + 1) + " igual en las dos palabras? " + iguales);}
   
    }
}

Y la última para comparar los datos:
Código: [Seleccionar]
/**
 * @author (David Martinez)
 * @version (a version number or a date)
 */
public class Compara
{
    /**
     * Constructor for objects of class Compara
     */
    public Compara()
    {
    }

    static int palabraLarga (String palabra1,String palabra2)
    {
        int larga = 0;
       
        if (palabra1.length() > palabra2.length()) { larga = palabra1.length();}
        else { larga = palabra2.length();}
        return larga;
    }
   
    static int palabraCorta (String palabra1,String palabra2)
    {
        int corta = 0;
        if (palabra1.length() < palabra2.length()) { corta = palabra1.length();}
        else { corta = palabra2.length();}
        return corta;
    }
   
    static boolean igualdad (String letra1,String letra2)
    {
        if (letra1.equals(letra2)){ return true;}
        else { return false;}
    }
}

Volver a agradecer el esfuerzo que se hace por ayudarnos a todos los que queremos aprender..
Espero vuestros consejos.
Gracias

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:Evitar excesivo anidamiento de instrucciones en Java. (CU00662B)
« Respuesta #4 en: 17 de Octubre 2015, 12:28 »
Hola, en tu nuevo ejercicio la separación en clases es una buena idea, al menos para practicar cómo debe ser el diseño de clases java. Es adecuado separar las tareas-datos en clases y que cada clase tenga sus responsabilidades (aunque para ejercicios simples donde se pretende trabajar un concepto en realidad no es necesario crear múltiples clases, pero se puede hacer para practicar).

La separación en clases que has realizado es buena, y la separación de tareas en métodos también es en general buena. En general felicitarte porque se ven buenas cosas en tu código.

Hay algunas cosas que serían mejorables, pero en general vas en la buena dirección así que intenta seguir por esa línea en los próximos ejercicios. Un ejemplo de a qué me refiero con cosas mejorables: si tienes dos palabras, es suficiente con tener un método palabraMasLarga, porque si una es la más larga la más corta es la otra, o al revés. En realidad no te harían falta dos métodos, sería suficiente con uno. En la clase con el main tampoco te harían falta dos while, te bastaría con uno que recorra la más larga y haga la comprobación de si existe letra correspondiente en la palabra más corta.

Lo que sí deberías corregir de forma inmediata son los nombres de las clases. A estas alturas ya deberías estar nombrando las clases de una forma correcta. Para nombrar clases debe hacerse siguiendo unas pautas, en https://www.aprenderaprogramar.com/foros/index.php?topic=3035.msg13698#msg13698 tienes una orientación de cómo se deben nombrar clases en Java.

Saludos

Pasandav

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 39
    • Ver Perfil
Re:Evitar excesivo anidamiento de instrucciones en Java. (CU00662B)
« Respuesta #5 en: 17 de Octubre 2015, 18:03 »
Gracias por los consejos.
Me está costando mucho pillar algunos conceptos (me he debido de poner mayor a aprender un lenguaje).
He conseguido poner todo en un solo while.
Los métodos masCorta y masLarga, en principio eran para poder mostrar en pantalla la longitud de las dos cadenas pero, es cierto que si omito esa parte, solo con uno se puede hacer... (bufff, que complicado).
Bueno, no cuelgo el nuevo código por no alargar más pero.... Muchas gracias de nuevo por todos los consejos.

Seguimos!!!

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:Evitar excesivo anidamiento de instrucciones en Java. (CU00662B)
« Respuesta #6 en: 19 de Octubre 2015, 08:27 »
¿Puedes colgar el código con la última versión? Esto puede servir de ayuda para otras personas que consulten y poder ver cómo se mejora un diseño. Gracias

Pasandav

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 39
    • Ver Perfil
Re:Evitar excesivo anidamiento de instrucciones en Java. (CU00662B)
« Respuesta #7 en: 19 de Octubre 2015, 15:11 »
¡¡Faltaría más!!

La clase que no voy a poner otra vez es "RegistroDeTeclado", (es la única que no ha cambiado).
He realizado cambios en los nombres de algunas clases y métodos (por la llamada de atención) :D
También en quitado un condicional del if en el método igualdad de la clase VisualizadorEnPantalla. ( iguales == false)
Bueno, ahí va:

Clase main:
Código: [Seleccionar]
/**
 * @author (David Martínez)
 * @version (a version number or a date)
 */
public class ComparadorDePalabras //Comienzo de la clase.
{
    public  static void main (String [] args)   // Comienzo del main
    {
        VisualizadorEnPantalla.pidePalabra (1); // Método que muestra mensaje para introducir palabra. Envía un int con el nº de palabra.
        String palabra1 = RegistroDeTeclado.introducePalabra(); // Almacena en "palabra1" el resultado devuelto por el metodo introducePalabra.

        VisualizadorEnPantalla.pidePalabra (2); // Método que muestra mensaje para introducir palabra. Envía un int con el nº de palabra.
        String palabra2 = RegistroDeTeclado.introducePalabra();// Almacena en "palabra2" el resultado devuelto por el metodo introducePalabra.
       
        int masLarga = ComprobadorDeLetras.palabraLarga(palabra1,palabra2); // Asigna el valor devuelto por el metodo palabraLarga al int "masLargo"
        int recorrePalabra=0;   // Inicializa int "recorrePalabra" = 0 para que comienze en el indice 0 del substring
        boolean esIgual=false;  // Inicializa boolean "esIgual" = false. (En principio la igualdad de letras es falsa.
        String letra1="";   // Inicializa "letra1" a cadena vacía.
        String letra2="";   // Inicializa "letra2" a cadena vacía.

        while (recorrePalabra < masLarga)   // Bucle mientras el valor de "recorrePalabra sea menor que el valor de "masLarga".
        {
            if (recorrePalabra >= palabra1.length())    // Si "recorrePalabra" es mayor que la longitud de "palabra1", ésta yo no tiene más letras (letra vacía).
            {
                letra1 = "";    // Se le asigna letra vacía (""), a "letra1".
                letra2 = palabra2.substring(recorrePalabra,recorrePalabra+1);   // "letra2" sigue almacenando letras hasta llegar a "masLarga"
            }
            else if (recorrePalabra >= palabra2.length())   // Si "recorrePalabra" es mayor que la longitud de "palabra2", ésta yo no tiene más letras (letra vacía).
            {
                letra2 = "";    // Se le asigna letra vacía (""), a "letra1".
                letra1 = palabra1.substring(recorrePalabra,recorrePalabra+1);   // "letra1" sigue almacenando letras hasta llegar a "masLarga"
            }
            else    // Si "recorrePalabra" no es mayor que "letra1" ni que "letra2". Se almacena en cada variable su letra correspondiente.
            {
             letra1 = palabra1.substring(recorrePalabra,recorrePalabra+1);
             letra2 = palabra2.substring(recorrePalabra,recorrePalabra+1);
            }
           
            esIgual = ComprobadorDeLetras.igualdad(letra1,letra2);  // Se almacena en booleana "esIgual" el valor devuelto del metodo "igualdad".
            VisualizadorEnPantalla.igualdad(esIgual,recorrePalabra,letra1,letra2);  // Se visualiza la igualdad en la pantalla.
            recorrePalabra = recorrePalabra + 1;    // Se incrementa en 1 "recorrePalabra" hasta llegar al valor de "masLarga"
        }
    }
}

Clase VisualizadorDePantalla:
Código: [Seleccionar]
/**
 * @author (David Martinez)
 * @version (a version number or a date)
 */
public class VisualizadorEnPantalla // Comienzo de clase.
{
    public VisualizadorEnPantalla() // Constructor (sin parametros).
    { }
   
    static void pidePalabra(int y)  // Metodo que muestra en pantalla la socilitud de datos con el int recibido como nº de palabra.
    {
        System.out.println("Introduce la " + y + "ª. palabra.");
    }
   
    static void igualdad (boolean iguales,int recorrido, String letra1,String letra2) // Metodo que muestra la igualdad.
    {
       if (letra1=="")  // Si los Strings no son iguales y "letra1" es letra vacía (""). Muestra mensaje.
       {
           System.out.println("La palabra1 no tiene letra " + (recorrido + 1));
       }
       else if (letra2=="") // Si los Strings no son iguales y "letra2" es letra vacía (""). Muestra mensaje.
       { System.out.println("La palabra2 no tiene letra " + (recorrido + 1));
       } 
       else // Si no hay letras vacias. Muestra si hay igualdad o no.
       {
           System.out.println("Letra " + (recorrido + 1) + " igual en las dos palabras? " + iguales);
       }
    }
}   // Fin de clase
Clase ComprobadorDeLetras:
Código: [Seleccionar]
/**
 * @author (David Martinez)
 * @version (a version number or a date)
 */
public class ComprobadorDeLetras    // Comienzo de la clase
{   
   
    public ComprobadorDeLetras()    //Constructor (Sin parametros).
    {
    }
    // Comprueba que longitud de los Strings recibidos es mas grande, almecena y devuelve dicha longitud en un int.
    static int palabraLarga (String palabra1,String palabra2)
    {
        int larga = 0;
        if (palabra1.length() > palabra2.length())
        {
            larga = palabra1.length();
        }
        else
        {
            larga = palabra2.length();
        }
        return larga;
    }
    // Comprueba si los strings recibidos son iguales. Devuelve un booleano con el resultado.
    static boolean igualdad (String letra1,String letra2)
    {
        if (letra1.equals(letra2))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}   // Fin de la clase.

De verdad, espero que le pueda servir a alguien.
Un saludo.

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".