Autor Tema: Java Consejos y trucos para optimización y código más limpio y eficiente mejorar  (Leído 748 veces)

CoduJ

  • Sin experiencia
  • *
  • Mensajes: 28
    • Ver Perfil
Buenas, espero que se encuentren bien. Me he estado preocupando por mantener un código más limpio y optimizado utilizando de momento la "estructura" de programar de arriba hacía abajo, sin utilizar el POO de Java.

De antemano decir que soy un "principiante", así que lamento el posible derrame de sangre en sus ojos.

Código: [Seleccionar]
import java.util.Scanner;
import java.util.Random;

public class Programa_empresa{
   public static void main(String args[]){
      Random CodeAlfaNumRand = new Random();
      Scanner Input = new Scanner(System.in);
      int ArticuloLitro[] = new int[3], ValorArticulo[] = new int[3], CodeAlfaNumArray = 0, Amplifiart = 0, OPc_1 = 0, ContadorBucle = 0, FacturasMayores = 0;
      ArticuloLitro[0] = 5; //5 Litros
      ArticuloLitro[1] = 15; //15 Litros
      ArticuloLitro[2] = 25; //25 Litros
      ValorArticulo[0] = 150; //valor articulos
      ValorArticulo[1] = 300;
      ValorArticulo[2] = 425;
      //caracteres para el codigo del articulo
      char CodeAlfaNumChar[] = new char[12];
      CodeAlfaNumChar[0] = 'A';
      CodeAlfaNumChar[1] = 'B';
      CodeAlfaNumChar[2] = 'C';
      CodeAlfaNumChar[3] = 'D';
      CodeAlfaNumChar[4] = 'E';
      CodeAlfaNumChar[5] = 'F';
      CodeAlfaNumChar[6] = 'G';
      CodeAlfaNumChar[7] = '0';
      CodeAlfaNumChar[8] = '1';
      CodeAlfaNumChar[9] = '2';
      CodeAlfaNumChar[10] = '3';
      CodeAlfaNumChar[11] = '4';
      char CodeAlfaNum[] = new char[6]; //cantidad de elementos del codigo alfanumerico     
     
      while(ContadorBucle <= 5){
         //declarar el codigo alfanumerico
         for(int i = 0; i < CodeAlfaNum.length; i++){
            CodeAlfaNumArray = CodeAlfaNumRand.nextInt(12);
            CodeAlfaNum[i] = CodeAlfaNumChar[CodeAlfaNumArray];
         }
         System.out.println("\t--- FARMACIA ---\nCual producto desea llevar:");
         System.out.println("1: Desinfectante " + ArticuloLitro[0] + "L | Valor: " + ValorArticulo[0]);
         System.out.println("2: Desinfectante " + ArticuloLitro[1] + "L | Valor: " + ValorArticulo[1]);
         System.out.println("3: Desinfectante " + ArticuloLitro[2] + "L | Valor: " + ValorArticulo[2]);
         OPc_1 = Input.nextInt();
         //si no selecciona correctamente
         while(OPc_1 < 1 || OPc_1 > 3){
            System.out.println("No ha seleccionado de manera correcta. . .");
            System.out.println("1: Desinfectante " + ArticuloLitro[0] + "L | Valor: " + ValorArticulo[0]);
            System.out.println("2: Desinfectante " + ArticuloLitro[1] + "L | Valor: " + ValorArticulo[1]);
            System.out.println("3: Desinfectante " + ArticuloLitro[2] + "L | Valor: " + ValorArticulo[2]);
            OPc_1 = Input.nextInt();
         }
         switch(OPc_1){
            case 1: //5 Litros
               System.out.print("Cuantos desea llevar: ");
               Amplifiart = Input.nextInt();           
               ValorArticulo[0] *= Amplifiart; //multiplicar el preico del producto
               ArticuloLitro[0] *= Amplifiart; //multiplicar cuantos litros hay en total
               System.out.println("\t--- FACTURA ---");
               System.out.print("Codigo del articulo: ");
                  for(int i = 0; i < CodeAlfaNum.length; i++){
                     System.out.print(CodeAlfaNum[i]);
                  }
               System.out.println("\nPrecio total: " + ValorArticulo[0]);
               System.out.println("Cantidad de litros comprados: " + ArticuloLitro[0]);
               if (ValorArticulo[0] > 600){
                  FacturasMayores++;               
               }
            break;
           
            case 2: //15 Litros
               System.out.print("Cuantos desea llevar: ");
               Amplifiart = Input.nextInt();           
               ValorArticulo[1] *= Amplifiart; //multiplicar el preico del producto
               ArticuloLitro[1] *= Amplifiart; //multiplicar cuantos litros hay en total
               System.out.println("\t--- FACTURA ---");
               System.out.print("Codigo del articulo: ");
                  for(int i = 0; i < CodeAlfaNum.length; i++){
                     System.out.print(CodeAlfaNum[i]);
                  }
               System.out.println("\nPrecio total: " + ValorArticulo[1]);
               System.out.println("Cantidad de litros comprados: " + ArticuloLitro[1]);
               if (ValorArticulo[1] > 600){
                  FacturasMayores++;               
               }           
            break;
           
            case 3: //25 Litros
               System.out.print("Cuantos desea llevar: ");
               Amplifiart = Input.nextInt();           
               ValorArticulo[2] *= Amplifiart; //multiplicar el preico del producto
               ArticuloLitro[2] *= Amplifiart; //multiplicar cuantos litros hay en total
               System.out.println("\t--- FACTURA ---");
               System.out.print("Codigo del articulo: ");
                  for(int i = 0; i < CodeAlfaNum.length; i++){
                     System.out.print(CodeAlfaNum[2]);
                  }
               System.out.println("\nPrecio total: " + ValorArticulo[2]);
               System.out.println("Cantidad de litros comprados: " + ArticuloLitro[2]);
               if (ValorArticulo[2] > 600){
                  FacturasMayores++;               
               }           
            break;           
         }
         ContadorBucle++;
      }
      if (FacturasMayores > 1){
         System.out.println("Hay " + FacturasMayores + " facturas que pasan de los $600");
      }else{
         System.out.println("Hay " + FacturasMayores + " factura que pasa de los $600");
      }
   }
}
« Última modificación: 27 de Octubre 2020, 10:15 por Alex Rodríguez »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 725
    • Ver Perfil
Re:Java - Consejos para optimización y código más limpio
« Respuesta #1 en: 13 de Mayo 2020, 19:38 »
Hola.
Algo importante es conseguir que el método main(), el principal, tenga el menor código posible. Que de una lectura rápida, uno se haga fácilmente una idea de lo que hace el programa y que lógica sigue.

Para ello puede resultar útil declarar variables fuera del main, no necesariamente todas, pero al menos sí las más importantes.
Además, al estar fuera del main, estas variables pasan a formar parte del ámbito global de la clase, lo cuál amplia su visibilidad y nos facilita poder usar métodos para así separar el código en fragmentos menores.
Estos  métodos al estar fuera del main, no podrían tener acceso a las variables que estuvieran dentro del main, ya que su visibilidad se limitaría al interior del main.

Pero si las declaramos fuera, tienen visibilidad absoluta y los métodos pueden interactuar con ellas fácilmente.

Con esto, conseguimos que el main se quede más reducido y legible.
Por ejemplo, la parte donde declaras los arrays ArticuloLitro, ValorArticulo, CodeAlfaNumChar y les das valores.
Son muchas líneas de código que podemos extraer del main y ponerlas en un método separado.


Otra cosa que me he fijado que se puede optimizar, es que cuando pides elegir articulo entre 1 y 3, haces un switch, y en los 3 cases tienes exactamente el mismo código escrito tres veces.
Solo cambia el indice para elegir artículo.
Si el usuario elige 1, tu accedes al 0
Si elige 2, acceder al 1 y si elige 3, accedes al 2....

Si te fijas, no necesitas repetir tres veces el código, solo necesitas restarle -1 a la opción del usuario y así accederías al artículo correcto.

Otra cosa, para el bucle principal usas un while() que se repite 6 veces. Esto es correcto y funciona de maravilla.
Pero si tienes claro que quieres que se repita 6 veces, es mejor usar un bucle for().
Más que nada, porque al leer el código, si un programador ve que has usado un for(), ya tiene la certeza de que el programa está pensado para repetirse un número determinado de veces.
Pero si ve un while(), la tendencia es pensar que se va a ejecutar un número INdeterminado de veces. Luego verá que no es así, pero la primera impresión que se llevará el lector puede ser errónea.

Más cosas. En Java, por convención, los métodos, nombres de variables (incluidos arrays), de objetos... siempre empiezan en minúscula.
Solo los nombres de las clases empiezan con mayúscula.
Por ejemplo Scanner, String, Integer, Object, MiFactura, Programa_empresa....

Por cierto, tampoco es costumbre usar línea de subrayado para separa nombres. En otros lenguajes sí, pero en Java la convención es usar el sistema CamelCase, es decir, cada palabra compuesta hacer que comience con mayúscula.
Así, Programa_empresa sería --> ProgramaEmpresa

Puedes escribirlo como te de la gana, y a Java le va a dar igual. El programa no va a funcionar ni mejor ni peor.
Pero es una de las normas que todos los programadores Java suelen cumplir, entonces, de nuevo, alguien que lea tu código puede confundir el nombre de una variable, con el de una clase, si ambas las escribes con la primera letra en mayúsculas.
Por eso conviene cumplir estas convenciones, por temas de legibilidad.

Dicho esto, así es como podría quedar tu clase aplicando estos cambios (excepto el de las mayúsculas, eso lo dejo a tu criterio).

Código: [Seleccionar]
public class Programa_empresa{

//Variables y objetos de ámbito global
static Random CodeAlfaNumRand = new Random();
static Scanner Input = new Scanner(System.in);
static int ArticuloLitro[] = new int[3];
static int ValorArticulo[] = new int[3];
static int CodeAlfaNumArray = 0, Amplifiart = 0;
static int OPc_1 = 0, FacturasMayores = 0;
static char CodeAlfaNumChar[] = new char[12];
static char CodeAlfaNum[] = new char[6]; //cantidad de elementos del codigo alfanumerico

//Programa principal
public static void main(String args[]){

inicializarArrays(); //Método que inicializa con valores los arrays

for (int j = 0; j <= 5; j++){

declararCodigoAlfa(); //declarar el codigo alfanumerico

do {
System.out.println("\t--- FARMACIA ---\nCual producto desea llevar:");
System.out.println("1: Desinfectante " + ArticuloLitro[0] + "L | Valor: " + ValorArticulo[0]);
System.out.println("2: Desinfectante " + ArticuloLitro[1] + "L | Valor: " + ValorArticulo[1]);
System.out.println("3: Desinfectante " + ArticuloLitro[2] + "L | Valor: " + ValorArticulo[2]);
OPc_1 = Input.nextInt();

if (OPc_1 < 1 || OPc_1 > 3)
System.out.println("No ha selecciona de manera correcta...\n");
else {
System.out.print("Cuantos desea llevar: ");
Amplifiart = Input.nextInt();           
ValorArticulo[OPc_1 - 1] *= Amplifiart; //multiplicar el preico del producto
ArticuloLitro[OPc_1 - 1] *= Amplifiart; //multiplicar cuantos litros hay en total
System.out.println("\t--- FACTURA ---");
System.out.print("Codigo del articulo: ");
for(int i = 0; i < CodeAlfaNum.length; i++){
System.out.print(CodeAlfaNum[i]);
}
System.out.println("\nPrecio total: " + ValorArticulo[OPc_1 - 1]);
System.out.println("Cantidad de litros comprados: " + ArticuloLitro[OPc_1 - 1]);
if (ValorArticulo[0] > 600){
FacturasMayores++;               
}
}

}while(OPc_1 < 1 || OPc_1 > 3);

} //Fin del bucle for

if (FacturasMayores > 1){
System.out.println("Hay " + FacturasMayores + " facturas que pasan de los $600");
}else{
System.out.println("Hay " + FacturasMayores + " factura que pasa de los $600");
}
}

//Métodos de la clase

private static void inicializarArrays() {
ArticuloLitro[0] = 5; //5 Litros
ArticuloLitro[1] = 15; //15 Litros
ArticuloLitro[2] = 25; //25 Litros
ValorArticulo[0] = 150; //valor articulos
ValorArticulo[1] = 300;
ValorArticulo[2] = 425;
//caracteres para el codigo del articulo
CodeAlfaNumChar[0] = 'A';
CodeAlfaNumChar[1] = 'B';
CodeAlfaNumChar[2] = 'C';
CodeAlfaNumChar[3] = 'D';
CodeAlfaNumChar[4] = 'E';
CodeAlfaNumChar[5] = 'F';
CodeAlfaNumChar[6] = 'G';
CodeAlfaNumChar[7] = '0';
CodeAlfaNumChar[8] = '1';
CodeAlfaNumChar[9] = '2';
CodeAlfaNumChar[10] = '3';
CodeAlfaNumChar[11] = '4';
}

private static void declararCodigoAlfa() {
for(int i = 0; i < CodeAlfaNum.length; i++){
CodeAlfaNumArray = CodeAlfaNumRand.nextInt(12);
CodeAlfaNum[i] = CodeAlfaNumChar[CodeAlfaNumArray];
}
}
}

Como puedes ver, el main se ha quedado mucho más reducido. Y el código es casi el mismo. Solo se ha reducido el código del switch, que ya no es necesario repetirlo.
El resto sigue estando ahí, solo que fuera del método main.

Bien, revisada la estética del programa, ahora quiero hacerte notar una cosa sobre la lógica, que me parece que no es correcta.
Cuando se selecciona un artículo y su cantidad, para calcular el precio y la cantidad que se lleva, estás modificando los valores en los arrays de artículos, porque haces la multiplicación directamente sobre ellos.
Lo marco en rojo.

Citar
               System.out.print("Cuantos desea llevar: ");
               Amplifiart = Input.nextInt();           
               ValorArticulo[OPc_1 - 1] *= Amplifiart; //multiplicar el preico del producto
               ArticuloLitro[OPc_1 - 1] *= Amplifiart; //multiplicar cuantos litros hay en total

Esto produce un efecto indeseado. Y es que la primera vez que se muestran en pantalla las opciones, salen bien. Garrafas de 5L, de 15L y de 25L
Pero al hacer una compra, la siguiente vez que se muestran, estos valores han sido modificados por la compra anterior.
Mira:
Citar
   --- FARMACIA ---
Cual producto desea llevar:
1: Desinfectante 5L | Valor: 150 //Valor correcto ;)
2: Desinfectante 15L | Valor: 300
3: Desinfectante 25L | Valor: 425
1
Cuantos desea llevar: 1000
   --- FACTURA ---
Codigo del articulo: C0D4AC
Precio total: 150000
Cantidad de litros comprados: 5000
   --- FARMACIA ---
Cual producto desea llevar:
1: Desinfectante 5000L | Valor: 150000 //WTF!! :0
2: Desinfectante 15L | Valor: 300
3: Desinfectante 25L | Valor: 425

Habría que cambiar esa lógica. El cálculo del importe y guardado de este no debería hacerse en los arrays de artículos. Estos arrays deberían ser intocables.

Dale un par de vueltas a ver que se te ocurre.

Un saludo y muchas gracias por participar en el foro
« Última modificación: 13 de Mayo 2020, 19:43 por Kabuto »
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

CoduJ

  • Sin experiencia
  • *
  • Mensajes: 28
    • Ver Perfil
Re:Java - Consejos para optimización y código más limpio
« Respuesta #2 en: 15 de Mayo 2020, 02:11 »
¡Muchísimas gracias Kabuto! Realmente me ayudaste. No me había dado cuenta de ese tonto error, lo arreglaré.
Quizás envié más código que quisiera compartir, solo para no volver a crear otro tema, espero que no sea problema.
« Última modificación: 15 de Mayo 2020, 17:53 por Alex Rodríguez »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 725
    • Ver Perfil
Re:Java - Consejos para optimización y código más limpio
« Respuesta #3 en: 15 de Mayo 2020, 12:28 »
Comparte el código que quieras, el foro está a tu disposición.
Un saludo.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

 

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