Autor Tema: Errores más habituales en el diseño de clases Java y métodos CU00666B  (Leído 4368 veces)

Pasandav

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 39
    • Ver Perfil
Mi solución para el ejercicio CU00666B.

Antes, una pregunta: ¿Es muy "farragoso" para vosotros que ponga tantas clases para cada ejercicio?

En caso afirmativo, para los próximos intentaré meter todo en el main.

Gracias

Código: [Seleccionar]
import java.util.ArrayList;
/**
 * Write a description of class ListaNombres here.
 *
 * @author (David Martínez)
 * @version (a version number or a date)
 */
public class ListaCantantesFamosos
{
    // Esta clase representa una lista de nombres manejada con la clase ArrayList de Java
    private String nombreDeCantante; // Establecemos atributo nombre de la lista.
    private ArrayList <String> listaDeCantantes; // Declaramos un ArrayList que contiene objetos String.
   
    public ListaCantantesFamosos () // Constructor, crea una lista y añade 3 nombres
    {
        listaDeCantantes = new ArrayList <String> ();
        listaDeCantantes.add ("Michael Jackson");
        listaDeCantantes.add ("Juan Luis Guerra");
        listaDeCantantes.add ("Juanes");
    } // Cierre del constructor.
   
    public void añadeDatos (String valor_nombre) // Añade al ArrayList el nombre introducido.
    {
        listaDeCantantes.add (valor_nombre);
        listadoCompleto();  // Llama al metodo que muestra todo el contenido del ArrayList.
    } // Cierre del metodo.
   
    public String getNombre (int posicion)   // Método que devuelve el nombre almacenado en "posicion".
    {
        if (posicion >= 0 && posicion < listaDeCantantes.size()) 
        {
            return listaDeCantantes.get (posicion);
        }
        else
        {
            return "No existe nombre para la posición solicitada";
        }
    }
   
    public void listadoCompleto()   // Metodo que recorre todo el ArrayList y lo visualiza en pantalla
    {
        int posicion = 0;
       
        for (String nombre:listaDeCantantes)
        {
        VisualizadorDeMensajes.listaDeCantantes (posicion,nombre);
        posicion ++;
        }   
    }
   
    public int getTamaño()  // Metodo que devuelve el tamaño de la lista.
    {
        return listaDeCantantes.size();
    }  // Metodo que devuelve el tamaño de la lista.
}   //Cierre de clase


Código: [Seleccionar]
import java.util.Scanner;
/**
 * Write a description of class RegistroTeclado here.
 *
 * @author (David Martínez)
 * @version (a version number or a date)
 */
public class RegistroTeclado
{
    String teclado; // Variable para crear objeto Scanner.
   
    public  RegistroTeclado()   // El constructor llama al metodo que crea el objeto Scanner
    {
        solicitudEntradaTeclado();
    }
   
    static String solicitudEntradaTeclado() // Metodo que crea el objeto Scanner.
    {
       Scanner teclado = new Scanner (System.in);
       String registroTeclado = teclado.nextLine();
       return registroTeclado;   // Devuelve el texto introducido como String
    } 
   
    static int masDatos(String mas) // Comprueba si se introduce "s", "n" u otra letra
    {
        String masdatos= mas.toLowerCase();
        int respuesta=0;
        do{ // Bucle que se repite, mientras "respuesta = 0".
            if (masdatos.equalsIgnoreCase("s")) { respuesta = 1;}   // si se recibe "s" respuesta = 1 (Se introducen más datos.
            else if (masdatos.equalsIgnoreCase("n")){ respuesta = 2;}   // Si se recibe "n" respuesta = 2 (No se introducen más datos.
            else {
                VisualizadorDeMensajes.entradaIncorrecta(); // Si no es ni "s" ni "n", Se muestra mensaje aclaratorio.
                masdatos = solicitudEntradaTeclado();   // Se vuelve a socilitar la introdución de datos.
            }
        } while (respuesta==0); // Fin de Do-While.
   
        return respuesta;   // Devuelve el valor de "respuesta" (1 o 2)
    }
   
}


Código: [Seleccionar]
/**
 * Clase que muestra los mensajes por pantalla.
 *
 * @author (David Martínez)
 * @version (a version number or a date)
 */
public class VisualizadorDeMensajes
{   
    public VisualizadorDeMensajes()
    {     
    }
   
    static void solicitudDeDatos()   // Metodo para mostrar mensaje de introducción de datos
    {
       System.out.println("Por favor, introduzca nombre de el/la cantante");
    }
   
    static void listaDeCantantes(int posicion,String nombre)    // Muestra el dato de ArrayList de situado en "posicion" y "nombre"
    {
      System.out.println("Posición de la lista " + posicion + " " + nombre.toUpperCase() );  // Lo muestra en Mayusculas.
    }   
   
    static void volverAIntoducirDatos() // Muestra la pregunta de seguir introduciendo datos.
    {
    System.out.println("¿Desea volve a introducir otro/a cantante? (S/N): ");
    }
    static void entradaIncorrecta() // Muestra que hay que introducir o S o N.
    {
        System.out.println("Por favor, responda (S/N): ");   
    }
}


Código: [Seleccionar]
/**
 * Write a description of class TestCantantes02 here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class TestCantantes02    // Inicio de Clase
{
    public TestCantantes02()    // Constructor.
    {
    }

    public static void main (String[]args)  // Inicio del main
    {
        ListaCantantesFamosos Lista = new ListaCantantesFamosos();  // Creamos objeto ArrayList (Lista)
       
        // Bucle que se repite mientras "respuesta" sea diferente de 2 (no introducir mas datos).

        int respuesta=0;    // Respuesta= 0 (Cualquier tecla) - Respuesta = 1 (n) - Respuesta = 2 (n)
     
        while (respuesta!=2){
             VisualizadorDeMensajes.solicitudDeDatos(); // Metodo que muestra el mensaje para introducir un/a cantante
             String nuevoCantante = RegistroTeclado.solicitudEntradaTeclado (); // Almacena el valor de teclado en nuevoCantante.
             Lista.añadeDatos(nuevoCantante);   // Metodo que añade el valor introducido en la lista y muestra la lista completa.
             VisualizadorDeMensajes.volverAIntoducirDatos();    // Metodo que muestra si se quieren introducir más datos.
             String masDatos = RegistroTeclado.solicitudEntradaTeclado (); // Añade el valor de teclado en variable masDatos
             respuesta = RegistroTeclado.masDatos(masDatos);    // Llama al metodo que comprueba si el valor introducido es correcto.
        }   // Fin del While.
    }   // Fin del main.
}   // Fin de la clase.
« Última modificación: 22 de Octubre 2015, 09:53 por Alex Rodríguez »

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:Solución: For extendido - CU00666B
« Respuesta #1 en: 22 de Octubre 2015, 09:52 »
Hola David, no es farragoso que pongas varias clases siempre que cada clase tenga un contenido mínimo (es decir, no tendría sentido crear una clase para poner sólo dos líneas por ejemplo) y siempre que sea adecuado para un buen diseño. Si es así, te sirve para practicar con programación orientada a objetos.

Sobre el ejercicio los comentarios serían:

MISMOS QUE PARA EL EJERCICIO ANTERIOR:

Incoherencia: tener un atributo en la clase ListaCantantesFamosos denominado nombreDeCantante. Ese atributo debería llamarse nombreDeLaLista.

private String nombreDeCantante; // Establecemos atributo nombre de la lista.

Preferible no usar eñes en nombres de atributos, clases o métodos. Por eso es mejor addDatos que añadeDatos

Los métodos en general deben ser public y no void, por ejemplo:

Mal: static void solicitudDeDatos(int veces,String tipoDeDatos)

Bien: public void solicitudDeDatos(int veces,String tipoDeDatos)

De este modo, para invocar un método antes tienes que crear un objeto usando new (no podrás hacerlo invocando directamente VisualizadorDeMensajes.solicitudDeDatos(...) ). ¡En la programación orientada a objetos se trabaja creando objetos, solo en algunas circunstancias especiales no se hace así!


PARA ESTE EJERCICIO EN CONCRETO

Un for extendido preferiblemente no lleva contador: leer este hilo, www.aprenderaprogramar.com/foros/index.php?topic=3210


En la clase ListaCantantesFamosos tienes un mal diseño que es este:

Código: [Seleccionar]
    public void añadeDatos (String valor_nombre) // Añade al ArrayList el nombre introducido.
    {
        listaDeCantantes.add (valor_nombre);
        listadoCompleto();  // Llama al metodo que muestra todo el contenido del ArrayList.
    } // Cierre del metodo.


Para hacer un buen diseño un método debe encargarse de hacer una cosa concreta, tener un fin concreto y no varios fines ni hacer varias cosas. El método añadeDatos o addDatos debe encargarse sólo de añadir datos, no es un buen diseño que en un método cuyo nombre indica que sirve para añadir datos pongamos una instrucción para mostrar datos por pantalla. ¿Mostrar algo por pantalla es añadir un dato? No, por lo tanto deben ser tareas separadas. Lo normal será que desde el main nos encarguemos primero de añadir el dato y luego de hacer que se muestre por pantalla.

Saludos

Pasandav

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 39
    • Ver Perfil
Re:Errores más habituales en el diseño de clases Java y métodos CU00666B
« Respuesta #2 en: 22 de Octubre 2015, 14:08 »
Bufff. Menudo "rapapolvo"!!  :o. No he dao ni una!!
En fin. Muchas gracias por todos los consejos, lo veo super complicado todo. Iba a enviar el ejercicio siguiente que si no miro por los foros no lo hubiera conseguido solucionar pero.... visto lo visto. Voy a volver hacia atrás, me cuesta mucho entender lo de crear objetos nuevos, pudiendo utilizar métodos de los propios objetos....
No se.... se me está haciendo grande esto..


Muchas gracias de nuevo. Seguiré intentándolo.

Pasandav

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 39
    • Ver Perfil
Re:Errores más habituales en el diseño de clases Java y métodos CU00666B
« Respuesta #3 en: 23 de Octubre 2015, 12:12 »
He intentado corregir todas las indicaciones.

No consigo sacar el objeto muestraEnPantalla del método listadoCompleto de la clase ListaCantantesFamosos, (no sé como enviar esos datos a la clase VisualizadorDeMensajes).

El resto creo que lo he "apañao", dentro de lo que he aprendido hasta ahora. Ya comentarás.

Muchas gracias por los consejos:

Código: [Seleccionar]
/**
 * Write a description of class TestCantantes02 here.
 *
 * @author (David Martínez)
 * @version (a version number or a date)
 */
public class TestCantantes02    // Inicio de Clase
{
    public TestCantantes02()    // Constructor.
    {
    }

    public static void main (String[]args)  // Inicio del main
    {
        ListaCantantesFamosos lista = new ListaCantantesFamosos();  // Creamos objeto ArrayList (Lista)
        RegistroTeclado teclado = new RegistroTeclado();
        VisualizadorDeMensajes muestraEnPantalla = new VisualizadorDeMensajes();
        int respuesta=0;    // Respuesta= 0 (Cualquier tecla) - Respuesta = 1 (n) - Respuesta = 2 (n)
        // Bucle que se repite mientras "respuesta" sea diferente de 2 (no introducir mas datos).
        while (respuesta!=2){
             muestraEnPantalla.solicitudDeDatos("nombre","cantante"); // Metodo que muestra el mensaje para introducir un/a cantante
             String nuevoCantante = teclado.solicitudEntradaTeclado (); // Almacena el valor de teclado en "nuevoCantante".
             lista.addCantanteALista(nuevoCantante);   // Metodo de "lista": Añade el valor del String "nuevoCantante" en el objeto "lista" y muestra la lista completa.
             lista.listadoCompleto();
             muestraEnPantalla.volverAIntoducirDatos("nombre","cantante");    // Metodo que muestra si se quieren introducir más datos.
             String seguir = teclado.solicitudEntradaTeclado ().toLowerCase(); // Añade el valor de teclado en variable masDatos
             respuesta = teclado.seguirIntroduciendoDatos(seguir);    // Llama al metodo que comprueba si el valor introducido es correcto.
        }   // Fin del While.
    }   // Fin del main.
}   // Fin de la clase.
Código: [Seleccionar]
/**
 * Clase que muestra los mensajes por pantalla.
 *
 * @author (David Martínez)
 * @version (a version number or a date)
 */
public class VisualizadorDeMensajes
{   
    public VisualizadorDeMensajes()
    {     
    }
   
    public void solicitudDeDatos(String dato,String tipo)   // Metodo para mostrar mensaje de introducción de datos
    {
       System.out.println("\nPor favor, introduzca " + dato + " de " + tipo +".");
    }
   
    public void solicitudDeDisco()    // Muestra la solicitud de introducir Disco.
    {
        System.out.println("Disco con más ventas:");
    }
   
    public void volverAIntoducirDatos(String dato,String tipo) // Muestra la pregunta de seguir introduciendo datos.
    {
    System.out.println("¿Desea introducir "+ dato + " de otro/a " + tipo +"? (S/N): ");
    }
   
    public void entradaIncorrecta() // Muestra que hay que introducir o S o N.
    {
        System.out.println("Por favor, responda (S/N): ");   
    }
   
    public void encabezadoDeLista(String tipo) // Muestra el encabezado de la lista.
    {
     System.out.println("La lista " + tipo + " contiene los siguientes datos:" ); 
    }
   
    public void listaPosicionYCantante (int posicion,String nombre)
    {
       System.out.println("En posicion: " + posicion + " - " + nombre ); 
   
    }
   
    public void listaCantanteYDisco(String nombre,String disco)    // Muestra el dato de ArrayList de situado en "posicion" y "nombre"
    {
      System.out.println("Cantante: " + nombre.toUpperCase() + "  Disco con más ventas: " + disco.toUpperCase() ); 
    }   
}
Código: [Seleccionar]
import java.util.Scanner;
/**
 * Write a description of class RegistroTeclado here.
 *
 * @author (David Martínez)
 * @version (a version number or a date)
 */
public class RegistroTeclado
{
    String teclado; // Variable para crear objeto Scanner.
    VisualizadorDeMensajes muestraEnPantalla = new VisualizadorDeMensajes();
   
    public  RegistroTeclado()   // El constructor llama al metodo que crea el objeto Scanner
    {
    }
   
    public String solicitudEntradaTeclado() // Metodo que crea el objeto Scanner.
    {
       Scanner teclado = new Scanner (System.in);
       String registroTeclado = teclado.nextLine();
       return registroTeclado;   // Devuelve el texto introducido como String
    } 
   
    public int seguirIntroduciendoDatos(String seguir) // Comprueba si se introduce "s", "n" u otra letra
    {
        int respuesta=0;
       
        do{ // Bucle que se repite, mientras "respuesta = 0".
            if (seguir.equalsIgnoreCase("s")) { respuesta = 1;}   // si se recibe "s" respuesta = 1 (Se introducen más datos.
            else if (seguir.equalsIgnoreCase("n")){ respuesta = 2;}   // Si se recibe "n" respuesta = 2 (No se introducen más datos.
            else {
                    muestraEnPantalla.entradaIncorrecta(); // Si no es ni "s" ni "n", Se muestra mensaje aclaratorio.
                    seguir = solicitudEntradaTeclado().toLowerCase();   // Se vuelve a socilitar la introdución de datos.
                 }
        } while (respuesta==0); // Fin de Do-While.
   
        return respuesta;   // Devuelve el valor de "respuesta" (1 o 2)
    }
   
}
Código: [Seleccionar]
import java.util.ArrayList;

public class ListaCantantesFamosos {
    private ArrayList <String> listaDeCantantes; // Declaramos un ArrayList que contiene objetos String.
   
    VisualizadorDeMensajes muestraEnPantalla = new VisualizadorDeMensajes();
   
    public ListaCantantesFamosos () // Constructor, crea una lista y añade 3 nombres
    {
        listaDeCantantes = new ArrayList <String> ();
        listaDeCantantes.add ("Michael Jackson");
        listaDeCantantes.add ("Juan Luis Guerra");
        listaDeCantantes.add ("Juanes");
    } // Cierre del constructor.
   
    public void addCantanteALista (String nombreCantante) // Añade al ArrayList el nombre introducido.
    {
        listaDeCantantes.add (nombreCantante);
    } // Cierre del metodo.
   
    public String getNombre (int posicion)   // Método que devuelve el nombre almacenado en "posicion".
    {
        if (posicion >= 0 && posicion < listaDeCantantes.size()) 
        {
            return listaDeCantantes.get (posicion);
        }
        else
        {
            return "No existe nombre para la posición solicitada";
        }
    }
   
    public void listadoCompleto()   // Metodo que recorre todo el ArrayList y lo visualiza en pantalla
    {
        for (String nombre:listaDeCantantes)
        {
        muestraEnPantalla.listaPosicionYCantante (listaDeCantantes.indexOf(nombre),nombre);
        }   
    }
   
   
    public int getTamaño()  // Metodo que devuelve el tamaño de la lista.
    {
        return listaDeCantantes.size();
    }  // Metodo que devuelve el tamaño de la lista.
}   //Cierre de clase
« Última modificación: 24 de Octubre 2015, 18:05 por Alex Rodríguez »

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:Errores más habituales en el diseño de clases Java y métodos CU00666B
« Respuesta #4 en: 24 de Octubre 2015, 18:10 »
Hola David dentro de la clase ListaCantantesFamosos puedes invocar un objeto VisualizadorDeMensajes. Pero tenemos dos alternativas para usarlo. Tú has declarado un VisualizadorDeMensajes como atributo de una ListaCantantesFamosos.

Pero otra opción (posiblemente preferible) es que el VisualizadorDeMensajes sea un atributo local al método.

El único atributo de la clase sería private ArrayList <String> listaDeCantantes;

El método quedaría así:

Código: [Seleccionar]
    public void listadoCompleto()   // Metodo que recorre todo el ArrayList y lo visualiza en pantalla
    {
        VisualizadorDeMensajes muestraEnPantalla = new VisualizadorDeMensajes();
        for (String nombre:listaDeCantantes)
        {
        muestraEnPantalla.listaPosicionYCantante (listaDeCantantes.indexOf(nombre),nombre);
        }   
    }

Si lo declaras como atributo, todo objeto ListaCantantesFamosos incorpora como atributo un VisualizadorDeMensajes, de este modo si creas diez listas de cantantes a su vez estarás creando diez visualizadores.

Si lo defines como atributo local al método, el visualizador se crea para ejecutar el método (temporalmente) y luego se destruye. En programación orientada a objetos es frecuente hacer esto.


Saludos

Pasandav

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 39
    • Ver Perfil
Re:Errores más habituales en el diseño de clases Java y métodos CU00666B
« Respuesta #5 en: 25 de Octubre 2015, 02:05 »
¡¡Caguen!!
Estuve a punto de mandarlo como me aconsejas, pero pensé: "Me llamarán la atención por crear un objeto dentro del método de otra clase". (Si es que, estoy "viejuno" ya "pa" tanto pensar). ;D

Pero.. habría manera de sacar el método "muestraEnPantalla" a su clase enviándole los parametros? o.... ¿Es "mu complicao" para mi "superbeginnerlevel" :o todavía?... o es normal hacerlo así??

Siempre agradecer toda vuestra ayuda.

A seguir "dandole"!!
Gracias

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:Errores más habituales en el diseño de clases Java y métodos CU00666B
« Respuesta #6 en: 26 de Octubre 2015, 12:57 »
Hola, el uso que te he indicado es un uso habitual en programación orientada a objetos. Creas objetos cuando te sean necesarios, aunque no a lo loco. A medida que vayas adquiriendo experiencia irás adquiriendo mayor destreza para todo esto. Saludos.

Pasandav

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 39
    • Ver Perfil
Re:Errores más habituales en el diseño de clases Java y métodos CU00666B
« Respuesta #7 en: 03 de Noviembre 2015, 11:24 »
Disculpa, no te había agradecido la ayuda. (La verdad es que tal y como funciona este foro... nunca son suficientes los agradecimientos). :D

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:Errores más habituales en el diseño de clases Java y métodos CU00666B
« Respuesta #8 en: 05 de Noviembre 2015, 14:32 »
Hola siempre agradecemos que se responda para saber que se leyó el mensaje. También agradecemos que se ayude a otros usuarios que sepan menos, respondiendo consultas en los foros, de esa forma conseguimos que los foros funcionen en base a ayuda mutua.

Saludos

 

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