Autor Tema: Adaptación de código -> orientación a objetos java  (Leído 4282 veces)

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Adaptación de código -> orientación a objetos java
« en: 04 de Julio 2014, 08:46 »
Hola. Presento ejercicio propuesto por César Krall "Moderador Global"
Una clase con main que usa dos clases accesorias "ManejadorDeVocales" y "ComparadorLetraALetra"
Ejercicio con el propósito de conducir el código a la Programación Orientada a Objetos.
Aquí envio 4 clases:

"Test2Texto"
Código: [Seleccionar]
/**
 * Detalles de la clase.
 * Clase con método main
 * @author (Toni)
 * @version (0)
 */
public class Test2Texto {
    // Atributos de la clase Test2Texto

    //Constructor para objetos de la clase Test2Texto
    public Test2Texto() {
        // Inicializa atributos

    } // Fin del constructor Test2Texto

    // Siguen los setters para los atributos de la clase Test2Texto

    // Ahora los getters para los atributos de la clase Test2Texto

    // Y seguidamente, procedimientos y funciones varios.
    public static void main (String [] args) {
        System.out.println ("Este es un test para trabajar con cadenas de texto introducidas por teclado.");
        String lectura = "";
        do {
            System.out.println ("Hay dos test disponibles. Escoja un número por favor:\n\t" +
                "1. Comparar dos cadenas letra a letra.\n\t2. Contar caracteres dentro de una frase.\n\tPulsar (ENTER) para terminar.");
            lectura = entradaATexto();
            if (lectura.length() == 0) {
                // saliendo
            } else if (lectura.substring(0,1).equals("1")) {
                miComparador();
            } else if (lectura.substring(0,1).equals("2")) {
                miContador();
            } else {
                System.out.println ("Opción inválida. Escoja otra vez por favor.");
            }
        } while (lectura.length() > 0);
        System.out.println ("\tFinalizado el test múltiple.");
    }// fin del main

    private static void miContador() {
        System.out.println ("Introducir el texto a inspeccionar.");
        String lectura = entradaATexto();
        ManejadorDeVocales texto = new ManejadorDeVocales(lectura);   
        do {
            System.out.println ("\tPara ver las estadísticas del texto, pulsar:\n" +
                "Una tecla cualquiera, \" \" (espacio) para ver toda la información recopilada, o (ENTER) para terminar.");
            lectura = entradaATexto();
            if (lectura.length() == 0) {
                //salir
            } else {
                if (!lectura.substring(0,1).equals(" ")) {texto.setCaracterVar(lectura); }
                texto.estadisticaLetras (lectura); // muestra estadísticas
            }
        } while (lectura.length() > 0);
        System.out.println ("Finalización de la consulta de caracteres para la frase:\n\t\"" + texto.getTexto() + "\"");
    }// fin de miContador

    private static void miComparador() {
        String lectura = "", entrada1 = "", entrada2 = "";
        boolean repetir = false;
        System.out.println ("Vamos a comparar dos cadenas de texto letra a letra.");
        do {
            System.out.println ("Introduzca la primera cadena, por favor.");
            lectura = entradaATexto();
            if (lectura.length() == 0) {
                repetir = true;
                System.out.println ("La entrada introducida no tiene contenido. Debe introducir algún texto.");
            } else {
                entrada1 = lectura;
                repetir = false;
            }
        } while (repetir);
        do {
            System.out.println ("Introduzca la segunda cadena, por favor.");
            lectura = entradaATexto();
            if (lectura.length() == 0) {
                repetir = true;
                System.out.println ("Entrada vacía. Debe introducir algún texto. Se pueden comparar cadenas vacías, pero no es divertido.");
            }else {
                entrada2 = lectura;
                repetir = false;
            }
        } while (repetir);
        ComparadorLetraALetra comparaYa = new ComparadorLetraALetra(entrada1, entrada2);
        comparaYa.resultadoDeLaComparacion();
        System.out.println ("\tFinalizada la comparación, vamos a otra cosa.");
    }

    private static String entradaATexto() {
        EntradaDeTeclado entrada = new EntradaDeTeclado();
        return entrada.getEntrada();
    }
} // Fin de la clase Test2Texto

"ManejadorDeVocales"
Código: [Seleccionar]
/**
 * Detalles de la clase.
 * Destripa el texto aportado en vocales, pulsación variable y resto de caracteres.
 * @author (Toni)
 * @version (0)
 */
public class ManejadorDeVocales {
    // Atributos de la clase ManejadorDeVocales
    private int numA, numE, numI, numO, numU, numVocales;
    private int numVar, numResto, numTotal;
    private String caracterVar;
    private String texto;
    //Constructor para objetos de la clase ManejadorDeVocales
    public ManejadorDeVocales(String texto) {
        // Inicializa atributos
        numA = 0; numE = 0; numI = 0; numO = 0;  numU = 0;  numVocales = 0;
        numVar = 0; numResto = 0;
        this.texto = texto;
        caracterVar = " ";
        numTotal = texto.length();
        cuentaLetras();
    } // Fin del constructor ManejadorDeVocales

    // Siguen los setters para los atributos de la clase ManejadorDeVocales
    /**
     * Establece el texto a manejar.
     */
    public void setTexto (String texto) {
        this.texto = texto;
        cuentaLetras();
    }
    /**
     * Método para establecer el carácter a inspeccionar.
     */
    public void setCaracterVar (String caracterVar) {
        this.caracterVar = caracterVar;
        cuentaLetras();
    }
    // Ahora los getters para los atributos de la clase ManejadorDeVocales
    public String getCaracterVar () { return caracterVar; }

    public String getTexto () { return texto; }

    public int getNumA () { return numA; }

    public int getNumE () { return numE; }

    public int getNumI () { return numI; }

    public int getNumO () { return numO; }

    public int getNumU () { return numU; }

    public int getNumVocales () { return numVocales; }

    public int getNumVar () { return numVar; }

    public int getNumResto () { return numResto; }

    public int getNumTotal () { return numTotal; }
    // Y seguidamente, procedimientos y funciones varios.
    /**
     * Médoto contador de letras.
     */
    private void cuentaLetras () {
        String letra = "";
        inicializaContadores();
        for (int i = 0; i < numTotal; i++) {
            letra = texto.substring(i,i+1).toUpperCase();
            if (letra.equals("A")) {
                numA ++; numVocales ++;
            } else if (letra.equals("E")) {
                numE ++; numVocales ++;
            } else if (letra.equals("I")) {
                numI ++; numVocales ++;
            } else if (letra.equals("O")) {
                numO ++; numVocales ++;
            } else if (letra.equals("U")) {
                numU ++; numVocales ++;
            } else if (letra.equals(caracterVar.substring(0,1).toUpperCase())) {
                numVar ++;
            } else {
                numResto ++;
            }// fin del if
        }//fin del for
    }//fin del cuentaLetras
    /**
     * Método para presentar resultados estadísticos...
     */
    public void estadisticaLetras(String valor) {
        if (valor.substring(0,1).toUpperCase().equals("A")) {//detecta la A
            grafismo("A");
            System.out.println ("Vocal A = \t" + numA + " veces. \t" + perCent(numA) + "%");
        } else if (valor.substring(0,1).toUpperCase().equals("E")) {//detecta la E
            grafismo("E");
            System.out.println ("Vocal E = \t" + numE + " veces. \t" + perCent(numE) + "%");
        } else if (valor.substring(0,1).toUpperCase().equals("I")) {//detecta la I
            grafismo("I");
            System.out.println ("Vocal I = \t" + numI + " veces. \t" + perCent(numI) + "%");
        } else if (valor.substring(0,1).toUpperCase().equals("O")) {//detecta la O
            grafismo("O");
            System.out.println ("Vocal O = \t" + numO + " veces. \t" + perCent(numO) + "%");
        } else if (valor.substring(0,1).toUpperCase().equals("U")) {//detecta la U
            grafismo("U");
            System.out.println ("Vocal U = \t" + numU + " veces. \t" + perCent(numU) + "%");
        } else if (valor.substring(0,1).equals(" ")) {
            if (numA > 0) { System.out.println ("Vocal A = \t" + numA + " veces. \t" + perCent(numA) + "%"); }
            if (numE > 0) { System.out.println ("Vocal E = \t" + numE + " veces. \t" + perCent(numE) + "%"); }
            if (numI > 0) { System.out.println ("Vocal I = \t" + numI + " veces. \t" + perCent(numI) + "%"); }
            if (numO > 0) { System.out.println ("Vocal O = \t" + numO + " veces. \t" + perCent(numO) + "%"); }
            if (numU > 0) { System.out.println ("Vocal U = \t" + numU + " veces. \t" + perCent(numU) + "%"); }
            System.out.println ("Suma vocales = \t" + numVocales + " letras. \t" + perCent(numVocales) + "%");
            if (numVar > 0) { System.out.println ("Tecla \"" + caracterVar.substring(0,1) + "\" = \t" + numVar + " veces. \t" + perCent(numVar) + "%"); }
            System.out.println ("Resto letras = \t" + numResto + " letras. \t" + perCent(numResto) + "%");
            System.out.println ("Total = \t" + numTotal + " letras. \t" + perCent(numTotal) + "%");
        } else {
            grafismo(caracterVar.toUpperCase().substring(0,1));
            System.out.println ("Tecla \"" + caracterVar.substring(0,1) + "\" = \t" + numVar + " veces. \t" + perCent(numVar) + "%");
        }//fin del if 
    }// fin de estadisticas
    // porcentaje de los valores.
    private  double perCent(int valor) {
        return (double)(valor * 1000 / numTotal) / 10;
    }

    private void inicializaContadores() {
        numA = 0; numE = 0; numI = 0; numO = 0;  numU = 0;  numVocales = 0;
        numVar = 0; numResto = 0;
    }

    // Este método muestra gráficamente la aparición del carácter inspeccionado.
    private void grafismo(String letra) {
        System.out.println (texto);
        String caracter = "";
        for (int i = 0; i < texto.length(); i++) {
            caracter = "-";
            if (texto.substring(i,i+1).toUpperCase().equals(letra)) { caracter = "|"; }
            System.out.print (caracter);
        }
        System.out.println();
    }
} // Fin de la clase ManejadorDeVocales

"ComparadorLetraALetra"
Código: [Seleccionar]
// import java.util.Scanner;
/**
 * Detalles de la clase.
 * Pide dos entradas, y compara letra por letra si son iguales o no.
 * @author (Toni)
 * @version (0)
 */
public class ComparadorLetraALetra {

    // Atributos de la clase ComparadorLetraALetra
    private String cadena1;
    private String cadena2;

    /**
     * Constructor para objetos de la clase ComparadorLetraALetra
     */
    public ComparadorLetraALetra(String cadena1, String cadena2) {
        // Inicializa atributos
        this.cadena1 = cadena1;
        this.cadena2 = cadena2;
    } // Fin del constructor ComparadorLetraALetra

    // Siguen los setters para los atributos de la clase ComparadorLetraALetra
    public void setCadena1 (String cadena1) { this.cadena1 = cadena1; }

    public void setCadena2 (String cadena2) { this.cadena2 = cadena2; }
    // Ahora los getters para los atributos de la clase ComparadorLetraALetra
    public String getCadena1 () { return cadena1; }

    public String getCadena2 () { return cadena2; }
    // Y seguidamente, procedimientos y funciones varios.
    /**
     * Método estrella. Presenta analogías y diferencias carácter a carácter.
     */
    public void resultadoDeLaComparacion () {
        System.out.println ("Vamos a comparar las entradas:\n\t" +
            "1 " + cadena1 + "\t y \t 2 " + cadena2);
        int largoMax = 0;//longitud de la entrada más larga
        int largo1 = cadena1.length();//longitud de la entrada1
        int largo2 = cadena2.length();//longitud de la enttrada2
        if (largo1 > largo2) {
            largoMax = largo1;
        } else {
            largoMax = largo2;
        }//se actualiza largoMax
        int porcion1 = 0, porcion2 = 0;//porción de las entradas que se va a mostrar
        for (int i = 0; i < largoMax; i++){
            if (i < largo1) { porcion1 = i+1;}//actualiza la porción a mostrar
            if (i < largo2) { porcion2 = i+1;}
            System.out.println ("\n¿La letra " + (i+1) + " es igual en las dos entradas?");
            System.out.print ("\t1 -" + cadena1.substring(0,porcion1) + "-\t2 -" +
                cadena2.substring(0,porcion2) + "-\nRespuesta " + (i+1) + ": ");//muestra las dos porciones
            if (largo1 < i+1) {
                System.out.println ("La entrada 1 no tiene letra " + (i+1));
            } else if (largo2 < i+1) {
                System.out.println ("La entrada 2 no tiene letra " + (i+1));
            } else {
                if (cadena1.substring(i,i+1).equals(cadena2.substring(i,i+1))) {
                    System.out.println ("True.");
                } else {
                    System.out.println ("False.");
                }// fin del if anidado
            }//fin del if
        }//fin del for
        System.out.println ("\nFin de la comparación.");
    }// fin de resultado
} // Fin de la clase ComparadorLetraALetra
y "EntradaDeTeclado"
Código: [Seleccionar]
import java.util.Scanner; //Importación del código de la clase Scanner desde la biblioteca Java
// Definimos una clase EntradaDeTeclado
/**
 * Detalles de la clase.
 *
 * @author (Toni)
 * @version (0)
 */
public class EntradaDeTeclado {

    // Atributos de la clase EntradaDeTeclado
    private String entradaTeclado;

    /**
     * Constructor para objetos de la clase EntradaDeTeclado
     */
    public EntradaDeTeclado() {
        // Inicializa atributos
        entradaTeclado = "";
        pedirEntrada();
    } // Fin del constructor EntradaDeTeclado

    // Siguen los setters para los atributos de la clase EntradaDeTeclado

    // Ahora los getters para los atributos de la clase EntradaDeTeclado

    // Y seguidamente, procedimientos y funciones varios.
    public void pedirEntrada() {
        Scanner entradaEscaner = new Scanner(System.in);
        entradaTeclado = entradaEscaner.nextLine();
    }
/**
 * Método predilecto. Devuelve el texto introducido por teclado.
 */
    public String getEntrada() { return entradaTeclado; }
   
    public int getLongitud() {
        return entradaTeclado.length();
    }// fin dle método
} // Fin de la clase EntradaDeTeclado

Saludos.
« Última modificación: 31 de Agosto 2014, 19:09 por Alex Rodríguez »

César Krall

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2078
  • No vales por lo que dices, sino por lo que haces
    • Ver Perfil
    • aprenderaprogramar.com
Re:Adaptación de código -> orientación a objetos.
« Respuesta #1 en: 04 de Julio 2014, 22:10 »
Hola Toni, una vez más te felicito pues se ve un gran trabajo y progreso en el código y en el diseño del código.

Voy a dejar aquí el link al código anterior para que otras personas puedan comparar un diseño y otro: https://www.aprenderaprogramar.com/foros/index.php?topic=998.0

Creo que te puedes dar por satisfecho, por el momento. Muchas personas con un buen nivel de programación cometen errores graves en el diseño del código por haber supuesto que era algo poco importante, pero es algo muy importante.

Aquí te dejo mis comentarios y cosas que veo mejorables no queriéndote decir que haya nada malo en el código planteado, sino para que tengas una opinión que te sirva para enfocar y mejorar tu aprendizaje como programador.


COMENTARIOS POR CLASES

ManejadorDeVocales: estás usando la invocación de métodos desde otros métodos, lo cual es indicador de que vas empezando a tener cierta soltura en el manejo de la programación. Aquí sí diría que has hecho un buen diseño de los métodos cuentaLetras() como método especializado en un proceso de "cálculo", mientras que estadisticaLetras sería un método especializado en presentar resultados.


EntradaDeTeclado: nada que comentar.


ComparadorLetraALetra:

has definido la clase con atributos. Otra opción hubiera sido definirla sin atributos, de modo que actuara como clase "manejadora" de información externa. En ocasiones nos interesará que una clase tenga atributos, y en otras ocasiones no.

El método resultadoDeLaComparacion es un método poco cohesivo: esto es una debilidad en el código que has planteado. Un método normalmente no realiza procesos como mostrar mensajes por pantalla y al mismo tiempo comparaciones, implementación de bucles, etc. Si un método se encarga de todo, estás incurriendo en el mismo defecto que usar el método main para meter ahí todo el código. Igual que cada clase se especializa en algo, cada método también debe especializarse en algo (principio de cohesión).

Es más "limpio" definir un método que se encargue de realizar algo concreto como la comparación entre dos letras y para mostrar la información llama a otro método que es el encargado de mostrar la información. Es decir, no mezclar cálculos con presentación de los resultados de los cálculos por pantalla. Se pueden usar tantos métodos como sea necesario y cada método debe tener una tarea clara y definida.


Test2Texto: creo que has captado bien la idea de lo que debe ser un método main en un programa. El main debe ser quien organiza y reparte juego, pero el peso del programa lo llevan los objetos. Todavía le veo un exceso de peso al main, pero se nota la clara mejoría.

Respecto a la ejecución del programa lo veo todo correcto. A modo de sugerencia, dado que estás considerando los espacios, te recomendaría que en vez de poner Total = xx letras pusieras Total = xx caracteres, ya que es más común hablar del carácter espacio que de la letra espacio.

Saludos,
Responsable de departamento de producción aprenderaprogramar.com

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Re:Adaptación de código -> orientación a objetos.
« Respuesta #2 en: 06 de Julio 2014, 08:44 »
Hola César. Que te voy a decir, que tú no sepas.

Estaba leyendo tu escrito cuando me ha sucedido algo extraño.
Si, ha sido... un agujero de gusano que me ha abducido.
He debido llegar al séptimo cielo por que estaba oyendo música celestial, y los oídos se me reblandecían de regalados que los tenía, pero...
Alto. Stop. Achtung. Creoquetengoretortijones...
No, es el ombligo, que me da un tirón y el cordón umbilical me devuelve a este lado.
Si, ya estoy de vuelta. Aunque todavía conservo media sonrisa, voy a hacer un esfuerzo y voy a hablar en serio, punto.

Como siempre César, tu Clase no tiene desperdicio.
Cosas como:
Comentarios afianzando conceptos.
Texto entrecomillado para enfatizar.
Meter una de cal y otra de arena.

Son maneras de hacer, que junto con la redacción hacen la lectura fácil, comprensible y aleccionable.

Por otro lado, tu exposición, me parece una pequeña joya.
La quiero comparar con el hallazgo arquelógico (no quiero decir antiguo, sino valioso) que precisa de estudio para extraer la máxima información.

Me gusta la programación "per se", no se hasta donde llegaré, pero el camino me lo hacéis fácil tú y tus compañeros del foro.

Saludos.

César Krall

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2078
  • No vales por lo que dices, sino por lo que haces
    • Ver Perfil
    • aprenderaprogramar.com
Re:Adaptación de código -> orientación a objetos.
« Respuesta #3 en: 06 de Julio 2014, 16:45 »
Gracias por tus comentarios, moderar los foros es un trabajo un tanto sufrido y está bien sonreir y recibir halagos de vez en cuando  8)

Aquí coincidimos un grupo variado de personas, pero casi todos tenemos en común que nos gusta la programación y no sabemos hasta donde llegaremos.

No estoy de acuerdo con "Qué te voy a decir, que tú no sepas". Yo posiblemente tenga más tiempo en esto que tú, pero sigo estudiando y aprendiendo, entre otras cosas se aprende revisando código hecho por otras personas y valorándolo y discutiendo posibles alternativas. Siempre se aprende algo...
Responsable de departamento de producción aprenderaprogramar.com

 

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