Botón para abrir el Menú Botón para cerrar el Menú
Logo da empresa Alura
Iniciar Sesión Nuestros Planes
Formaciones Conoce a Luri
  • Programación _
  • Front End _
  • Data Science _
  • DevOps _
  • Innovación y Gestión _
Artículos de Tecnología > Programación

Hacer que el código sea más sencillo con refactorización en Java

Alex Felipe
Alex Felipe
17/10/2023

Compartir

Mira este artículo:
  1. Entendiendo la refactorización de código
  2. Renombrar variables
  3. Extracción de métodos
  4. Conclusión

img-capa

Es muy común en nuestro día a día, como desarrolladores, lidiar con códigos escritos por otros desarrolladores, ya sea para comprender una regla de negocio o para la evolución del programa en general.

Para comprender mejor esta situación, consideremos una aplicación Java para un inventario de productos. En esta aplicación, tenemos el siguiente código:

public class ProductoDAO { 
	public List<Producto> lista(){ 
	// Implementación cualquiera que devuelva una lista de productos 
	} 
    public void productosResumidos(){ 
        List<Producto> prs = lista(); 
        for (Producto p : prs) { 
            String dse = p.getDescripcion().trim(); 
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < dse.length(); i++) { 
                if(i > 15) { 
                    sb.append("...");
                    break;
                } 
                sb.append(dse.charAt(i));
            } 
            String da = sb.toString(); 
            String vf = p.getValor().toString().replace(".", ","); 
            String df = p.getId() + " - " + da + " - $ " + vf; 	
            System.out.println(df); 
        } 
    } 
}

Tenga en cuenta que se trata de una clase DAO para productos. Para aclarar más el ejemplo, consideremos el siguiente modelo para la clase Producto:

public class Producto { 
    private Integer id; 
    private String descripcion; 
    private Double valor; 
    // Constructores, getters, setters y métodos
}

Cuando ejecutamos el método productosResumidos(), obtenemos el siguiente resultado:

 1 - Soda de ... - $ 5,0 
 2 - Bocadillo Doritos ... - $ 3,5 
 3 - Pan Blanco ... - $ 4,5 
 4 - Leche ... - $ 2,75 
 5 - Jugo ... - $ 4,0

Al observar el resultado, tenemos un resumen de los productos almacenados en el inventario. Sin embargo, al mirar rápidamente la implementación del método productosResumidos(), ¿es fácil comprender cómo se obtuvo este resultado? En principio, no...

Entendiendo la refactorización de código

En otras palabras, hemos llegado a una situación en la que tiene sentido detenerse y pensar en formas de mejorar nuestro código actual, ¿verdad?

Este proceso de mejora de código se conoce técnicamente como code refactoring (o refactorización de código).

Esta técnica, en general, consta de diversas prácticas que buscan mejorar el código en los siguientes aspectos:

  • Simplicidad: minimizar la cantidad de código.
  • Legibilidad: mejorar la comprensión del código para los seres humanos.
  • Rendimiento: aumentar la velocidad de ejecución.

En principio, puedes estar pensando:

"La refactorización es genial, pero si lo hago, ¿estaré modificando el comportamiento de mi aplicación?"

La primera impresión que tenemos durante este tipo de proceso es que nuestra aplicación será modificada y tendrá comportamientos diferentes.

Esto es bastante común, pero la idea de la refactorización es aplicar técnicas que solo modifiquen el aspecto visual del código, es decir, el comportamiento inicial sigue siendo el mismo.

Puede parecer demasiado bueno para ser verdad, ¿verdad? Entonces, apliquemos algunas técnicas de refactorización al código que vimos inicialmente y veremos la magia en acción.

Renombrar variables

La primera de las técnicas que aplicaremos será cambiar los nombres de las variables. Al principio puede parecer trivial, pero echemos un vistazo a un fragmento de nuestro código:

List<Producto> prs = lista(); 
for (Producto p : prs) { 
    String dse = p.getDescripcion().trim();
    // resto del código 
}

Para ti, ¿psr, p, dse tienen algún significado? Para mí y para cualquier persona que vea este código por primera vez, no tienen ningún significado a primera vista. Entonces, ¿qué tal si hacemos la siguiente modificación?

List<Producto> productos = lista(); 
for (Producto producto : productos) { 
    String descripcionSinEspacios = producto.getDescripcion().trim();
    // resto del código
}

Ahora queda claro que estamos tratando con una lista de productos, y para cada producto de la lista de productos estamos obteniendo una descripcionSinEspacios.

¡Observa que incluso es más fácil de leer! En otras palabras, durante el proceso de refactorización, renombrar variables facilita la lectura del código. Por tanto, cuanto más significativo sea el nombre de la variable, más fácil será su lectura. Ajustemos los otros puntos:

public void productosResumidos(){ 
    List<Producto> productos = lista();
    for (producto producto : productos) {
        String descripcionSinEspacios = producto.getDescripcion().trim();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < descripcionSinEspacios.length(); i++) {
            if(i > 15) { sb.append("...");
            break;
        } 
        sb.append(descripcionSinEspacios.charAt(i));
    } 
    String descripcionAjustada = sb.toString();
    String valorFormateado = producto.getValor().toString().replace(".", ","); 
    String descripcionFinal = producto.getId() + " - " + descripcionAjustada + " - $ " + valorFormateado; 
        System.out.println(descripcionFinal); 
    } 
}

Tenga en cuenta que la variable sb aún se mantiene en referencia a la instancia de la clase StringBuilder. Dado que es una instancia de una clase comprensible para la mayoría de desarrolladores y no tiene un nombre muy corto, no hay problema en mantenerla como sb.

En otras palabras, para casos en los que estamos creando una instancia de una clase con un nombre largo, podemos usar una abreviatura. En este caso, con el StringBuilder, podríamos incluso usar builder, que tendría suficiente significado.

Recuerda: durante este proceso de renombrar variables, lo más importante es que al leer el código, la lectura sea fácil y directa. Es decir, incluso para alguien que no conozca la implementación en profundidad, debería ser comprensible solo leyendo el código.

Extracción de métodos

Aunque nuestro código ha mejorado significativamente en términos de legibilidad, es claro, con nombres más claros para los seres humanos, pero es bastante complejo. Si observamos, tenemos muchas líneas dentro de un solo método.

Dado esta situación, ¿qué podemos hacer para solucionar este problema? Para este tipo de escenarios, podemos aplicar la conocida técnica como extracción de métodos. Ahora puedes estar pensando:

"Está bien, pero ¿cómo funciona esta técnica?"

Básicamente, durante la lectura del código, realizamos un análisis y vemos qué hace un conjunto de código, como este fragmento:

String descripcionSinEspacios = producto.getDescripcion().trim();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < descripcionSinEspacios.length(); i++) {
    if(i > 15) { 
        sb.append("...");
        break; 
    } 
    sb.append(descripcionSinEspacios.charAt(i));
} 
String descripcionAjustada = sb.toString();

Si observamos con atención, este código tiene como objetivo ajustar una descripción de un producto, ¿verdad? Entonces, ¿qué tal si convertimos todo este código en este método aquí?

private String ajustarDescripcion(Producto producto) {
    String descripcionSinEspacios = producto.getDescripcion().trim();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < descripcionSinEspacios.length(); i++) {
        if(i > 15) { 
            sb.append("...");
            break;
        } 
        sb.append(descripcionSinEspacios.charAt(i));
    } 
    return sb.toString(); 
}

Entonces, solo necesitamos realizar la siguiente llamada dentro de nuestro código anterior:

public void productosResumidos(){ 
    List<Producto> productos = lista(); 
    for (Producto producto : productos) {
        String descripcionAjustada = ajustarDescripcion(producto);
        String valorFormateado = producto.getValor().toString().replace(".", ","); 
        String descripcionFinal = producto.getId() + " - " + descripcionAjustada + " - $ " + valorFormateado; 
        System.out.println(descripcionFinal); 
    } 
}

¡Mira cómo nuestro método se ha reducido! Es aún más fácil de leer de esta manera y podemos hacer lo mismo con otros puntos del código. Por ejemplo, este:

String valorFormateado = producto.getValor().toString().replace(".", ",");

Básicamente, el código a la derecha formatea el valor de acuerdo con la moneda, ¿verdad? En este caso, nada nos impide extraer un método aquí también. ¿Qué tal si lo dejamos de esta manera?

private String formatearMoneda(Producto producto) { 
    return producto.getValor().toString() .replace(".", ","); 
}

Aprovechando, también podemos aplicar el mismo concepto al fragmento de código siguiente:

String descripcionFinal = producto.getId() + " - " + descripcionAjustada + " - $ " + valorFormateado;

Vamos a extraerlo a:

private String resumirLaDescripcion(Producto producto, String descripcionAjustada, String valorFormateado) { 
    return producto.getId() + " - " + descripcionAjustada + " - $ " + valorFormateado;
}

Ahora, veamos cómo se ve ese método inicial:

public void productosResumidos(){ 
    List<Producto> productos = lista();
    for (Producto producto : productos) {
        String descripcionAjustada = ajustarDescripcion(producto);
        String valorFormateado = formatearMoneda(producto);
        String descripcionFinal = resumirLaDescripcion(producto, descripcionAjustada, valorFormateado); 
        System.out.println(descripcionFinal);
    } 
}

Mucho más fácil de leer, ¿verdad? Incluso podemos simplificarlo más. En lugar de enviar 3 parámetros para crear la descripción final, podemos enviar solo el producto y llamar a los otros métodos dentro del método resumirLaDescripcion():

public void productosResumidos(){ 
    List<Producto> productos = lista();
    for (Producto producto : productos) {
        String descripcionFinal = resumirLaDescripcion(producto); 	      			 
        System.out.println(DescripcionFinal); 
    } 
} 
private String resumirLaDescripcion(Producto producto) { 
    String descripcionAjustada = ajustarDescripcion(producto);
    String valorFormateado = formatearMoneda(producto);
    return producto.getId() + " - " + descripcionAjustada + " - $ " + valorFormateado; 
}

Observa cuánto ha cambiado nuestro código:

public void productosResumidos(){ 
    List<Producto> productos = lista(); 
    for (Producto producto : productos) { 
        String descripcionFinal = resumirLaDescripcion(producto); 
        System.out.println(descripcionFinal); 
    } 
} 
private String resumirLaDescripcion(Producto producto) { 
    String descripcionAjustada = ajustarDescripcion(producto);
    String valorFormateado = formatearMoneda(producto);
    return producto.getId() + " - " + descripcionAjustada + " - $ " + valorFormateado;
} 
private String formatearMoneda(Producto producto) {
    return producto.getValor().toString() .replace(".", ",");
} 
private String ajustarDescripcion(Producto producto) {
    String descripcionSinEspacios = producto.getDescripcion().trim();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < DescripcionSinEspacios.length(); i++) {
        if(i > 15) { 
            sb.append("...");
            break;
        } 
        sb.append(DescripcionSinEspacios.charAt(i));
    } 
    return sb.toString();
    String da = sb.toString();
    String vf = p.getValor().toString().replace(".", ",");
    String df = p.getId() + " - " + da + " - $ " + vf; System.out.println(df);
}

Ahora, nuestro método productosResumidos() es mucho más fácil de entender. Sabemos inmediatamente que utiliza cada producto, obtenemos una Descripción final y la imprimimos.

Conclusión

Tenga en cuenta que, aunque el código parece complejo, al aplicar algunas técnicas de refactorización, hemos podido mejorar significativamente el aspecto de lectura y comprensión de nuestro código. En este caso, vimos la técnica de extracción de métodos y el cambio de nombres de variables a nombres más amigables. Si te gusta el tema, te animamos a profundizar en [Formación en Java Orientada a Objetos](Cursos Java Orientados a Objetos | Formación | Alura (aluracursos.com) ), que tenemos en Alura Latam!

img-autor

Alex Felipe

Instructor y desarrollador con experiencia en Java, Kotlin, Android. Creador de más de 40 cursos, como Kotlin, Flutter, Android, persistencia de datos, comunicación con Web API, personalización de pantalla, pruebas automatizadas, arquitectura de Apps y Firebase. Es experto en Programación Orientada a Objetos, siempre con el objetivo de compartir las mejores prácticas y tendencias en el mercado de desarrollo de software. Trabajó durante 2 años como editor de contenidos en el blog de Alura y hoy todavía escribe artículos técnicos.

Artículo traducido para Alura Latam por Brenda Souza

Artículo Anterior
Regex en C#: cómo utilizar expresiones regulares
Siguiente Artículo
Estructura de datos: computación práctica con Java

Ver otros artículos sobre Programación

Navegación

  • Planes
  • Instructores
  • Blog
  • Política de privacidad
  • Términos de uso
  • Sobre nosotros
  • Preguntas frecuentes

¡CONTÁCTANOS!

  • ¡Quiero entrar en contacto!

Blog

  • Programación
  • Data Science
  • Front End
  • Innovación y Gestión
  • DevOps

AOVS Sistemas de Informática S.A CNPJ 05.555.382/0001-33

SÍGUENOS EN NUESTRAS REDES SOCIALES

YouTube Facebook Instagram Linkedin Whatsapp Spotify

NOVEDADES Y LANZAMIENTOS

Aliados

  • Programa de aceleração Scale-Up Endeavor
  • En Alura somos unas de las Scale-Ups seleccionadas por Endeavor, programa de aceleración de las empresas que más crecen en el país.
  • Growth Academy 2021 do Google For Startups
  • Fuimos unas de las 7 startups seleccionadas por Google For Startups en participar del programa Growth Academy en 2021
Alura

Powered by

Caelum

AOVS Sistemas de Informática S.A CNPJ 05.555.382/0001-33

SÍGUENOS EN NUESTRAS REDES SOCIALES

YouTube Facebook Instagram Linkedin Whatsapp Spotify

Cursos

Cursos de Programación
Lógica de Programación | Java
Cursos de Front End
HTML y CSS | JavaScript | React
Cursos de Data Science
Data Science | Machine Learning | Excel | Base de Datos | Data Visualization | Estadística
Cursos de DevOps
Docker | Linux
Cursos de Innovación y Gestión
Transformación Ágil | Marketing Analytics

Alura

  • Educação em Tecnologia

    • logo fiap FIAP
    • logo casa do codigo Casa do Código
    • logo pm3 PM3 - Cursos de Produto
  • Mais Alura

    • logo alura start START BY Alura
    • logo alura lingua Alura Língua
    • logo alura para empresas Alura Para Empresas
    • logo alura latam Alura LATAM
  • Comunidade

    • logo tech guide Tech Guide
    • logo 7 days of code 7 days of code
    • logo Hipsters ponto Jobs Hipsters ponto Jobs
  • Podcasts

    • logo Hipster Network Hipster Network
    • logo Hipsters ponto Tech Hipsters ponto Tech
    • logo Dev sem fronteiras Dev sem Fronteiras
    • logo Like a Boss Like a Boss
    • logo IA Sob Controle IA Sob Controle
    • logo Mesa de Produto Mesa de Produto
    • logo Decode Decode
    • logo FIAPCast FIAPCast