🏠 Inicio ➡️ / 📖 Prework sesión 10
¡Bienvenidos a la última sesión del módulo Java Standard Edition! En esta sesión especial, haremos un recorrido integral por todos los temas clave que hemos trabajado a lo largo de las nueve sesiones anteriores.
Durante este tiempo, exploraste desde los fundamentos del lenguaje Java hasta conceptos avanzados de programación orientada a objetos, estructuras de datos, manejo de archivos, colecciones, herencia, buenas prácticas y manejo de errores. Ahora es momento de consolidar lo aprendido, repasar los puntos más importantes y aclarar cualquier duda pendiente.
Esta sesión está diseñada como un espacio de repaso y reflexión, donde podrás hacer conexiones entre los distintos temas, revisar conceptos esenciales y prepararte para afrontar futuros proyectos con una base sólida en Java.
- Consolidar los conocimientos adquiridos durante el módulo Java Standard Edition, repasando los conceptos clave de cada sesión: desde la sintaxis básica de Java y la POO, hasta el manejo de colecciones, archivos y buenas prácticas de desarrollo.
- Aclarar dudas y fortalecer la comprensión sobre temas fundamentales como clases, objetos, herencia, polimorfismo, colecciones, excepciones, estructuras de control, manejo de archivos y principios SOLID.
- Preparar al estudiante para aplicar estos conocimientos en proyectos reales o en etapas avanzadas de formación, fomentando la confianza, la claridad y el pensamiento estructurado en el desarrollo con Java.
Este Prework está diseñado para conocer el contenido que se practicará durante la sesión en vivo. Por favor no lo omitas. Toma notas de lo que consideres relevante y guarda tus preguntas o dudas para resolverlas en la sesión.
Bienvenid@ al decimo Prework del módulo. A continuación, te presentamos el tiempo estimado de lectura por tema, para que puedas revisar todos los recursos al máximo:
| 📖 Temario | 🕰️ Tiempo sugerido |
|---|---|
| Tema 01. Repaso integral del modulo | 15 min |
¡Comencemos! 🏁
A lo largo de estas nueve sesiones, has recorrido un camino de aprendizaje en el que desarrollaste habilidades esenciales para convertirte en un programador Java más sólido, estructurado y profesional. Este círculo de estudio representa una excelente oportunidad para reflexionar sobre lo que has aprendido y fortalecer tu dominio del lenguaje.
En este repaso, destacaremos los conceptos clave y aprendizajes de cada sesión, permitiéndote recordar, conectar ideas y reconocer el gran avance que has logrado en tu proceso de formación.
¡Vamos con todo para cerrar con claridad y confianza este módulo! 💪🚀
Sesión 01. Introducción a la programación orientada a objetos en Java
En esta primera sesión dimos nuestros primeros pasos en el mundo de Java, un lenguaje de programación que ha marcado la industria por su robustez, portabilidad y enfoque en la Programación Orientada a Objetos (POO).
🧠 ¿Qué aprendiste?
- Comprendiste que Java es un lenguaje:
- Multiplataforma gracias a la Java Virtual Machine (JVM), que permite ejecutar un mismo programa en distintos sistemas operativos.
- Orientado a objetos, lo que significa que todo en Java gira en torno a clases y objetos.
- Seguro y estable, ideal para desarrollar aplicaciones empresariales, móviles, web y de escritorio.
🔧 Preparación del entorno
- Aprendiste a instalar y configurar las herramientas necesarias para desarrollar en Java:
- Java Development Kit (JDK): el conjunto de herramientas que permite compilar y ejecutar programas Java.
- IntelliJ IDEA Community Edition: un entorno de desarrollo profesional que facilita la escritura, navegación y depuración de código.
💡 Introducción al paradigma POO
- Ingresaste al paradigma que define la forma moderna de programar:
- Clases: estructuras que representan entidades con atributos (datos) y métodos (acciones).
- Objetos: instancias concretas de una clase.
- Encapsulamiento: control de acceso a los datos para proteger la integridad del objeto.
- Herencia: reutilización de código mediante jerarquías entre clases.
- Polimorfismo: posibilidad de que una misma operación tenga comportamientos distintos según el objeto que la ejecute.
- Abstracción: capacidad de representar solo lo esencial de una entidad, ocultando los detalles innecesarios.
🆕 Características modernas de Java
- Conociste nuevas características del lenguaje introducidas en versiones recientes:
record: un tipo especial de clase para definir objetos inmutables de forma sencilla, ideal para modelos de datos.sealed classes: permiten restringir qué clases pueden heredar de una clase base, mejorando la seguridad y el control del diseño.
Esta sesión sentó las bases conceptuales y técnicas para el resto del curso. Fue el punto de partida para entender no solo cómo escribir código en Java, sino cómo pensar en objetos, estructurar soluciones escalables y adoptar buenas prácticas desde el inicio.
Sesión 02: Tipos de datos y sentencias de control
En esta sesión, exploraste los fundamentos que permiten construir la lógica de cualquier programa en Java. Aprendiste a trabajar con datos, realizar operaciones y controlar el flujo de ejecución, habilidades clave para que tu código tome decisiones y repita tareas eficientemente.
🔠 Tipos de datos y uso de var
-
Comprendiste que en Java los tipos de datos primitivos son la base para almacenar información:
int,double,boolean,char, entre otros.
-
Aprendiste a declarar variables usando el tipo correspondiente, y también a usar
var, una palabra clave que permite que el compilador infiera el tipo automáticamente:- Ideal para reducir redundancia, pero requiere que el valor inicial sea claro y legible.
🔁 Conversión de tipos (casting)
- Estudiaste cómo convertir valores de un tipo a otro:
- Conversión implícita (de tipo menor a mayor): por ejemplo,
int → long. - Conversión explícita (de tipo mayor a menor): por ejemplo,
double → int, con posible pérdida de información.
- Conversión implícita (de tipo menor a mayor): por ejemplo,
➕ Operadores y expresiones
-
Dominar los operadores es esencial para crear condiciones y realizar cálculos. Aprendiste a utilizar:
- Aritméticos:
+,-,*,/,% - Relacionales:
==,!=,<,>,<=,>= - Lógicos:
&&,||,! - Asignación y combinación:
=,+=,-=, etc. - Incremento/Decremento:
++,--
- Aritméticos:
-
También conociste el concepto de precedencia y cómo afecta el orden de evaluación en las expresiones complejas.
🔀 Estructuras de control condicional
-
if,else if,else: estructuras básicas para tomar decisiones. -
Introducción a la nueva sintaxis de
switch(Java 12+), que permite:- Mayor claridad con el uso de
-> - Asignaciones directas de valores
- Eliminación del uso obligatorio de
break
- Mayor claridad con el uso de
🔄 Bucles y repetición Aprendiste a repetir instrucciones usando diferentes estructuras:
for: ideal cuando conoces el número de iteraciones.while: se ejecuta mientras se cumpla una condición.do-while: garantiza al menos una ejecución.for-each: útil para recorrer colecciones sin manejar índices directamente.
🧠 Buenas prácticas en estructuras de control
- Usa
ifyswitchsolo cuando sea necesario y evita anidar demasiadas condiciones. - Emplea el bucle más adecuado para el problema que estás resolviendo.
- Ten cuidado con los bucles infinitos y asegúrate de que la condición de salida sea clara.
Esta sesión fue esencial para comenzar a escribir código dinámico, interactivo y con lógica propia. Aprendiste que un buen manejo de datos y estructuras de control te permite tomar decisiones, validar condiciones, y ejecutar acciones repetitivas sin duplicar código.
Sesión 03. Clases y objetos: crea aplicaciones que permitan el ingreso de información
Esta sesión fue clave para profundizar en los pilares de la Programación Orientada a Objetos (POO). Aprendiste a crear tus propias clases, instanciar objetos y definir métodos para que estos objetos puedan ejecutar acciones específicas. Todo esto representa el corazón del desarrollo en Java.
🧱 Clases y objetos
- Clase: es una plantilla que define las características (atributos) y comportamientos (métodos) de un tipo de objeto.
- Objeto: es una instancia de una clase, es decir, una versión concreta que puede almacenar información y ejecutar métodos.
📌 Ejemplo:
class Perro {
String nombre;
void ladrar() {
System.out.println("¡Guau!");
}
}Perro miPerro = new Perro();
miPerro.nombre = "Max";
miPerro.ladrar();🔧 Constructores
- Son métodos especiales que se ejecutan automáticamente al crear un objeto.
- Pueden ser:
- Por defecto (sin parámetros)
- Con parámetros (para inicializar atributos directamente)
- De copia (para duplicar objetos)
- Puedes tener múltiples constructores usando sobrecarga, es decir, diferentes versiones con distintos parámetros.
✏️ Métodos con parámetros y retorno
- Los métodos pueden recibir valores (parámetros) y también devolver resultados:
- Métodos
void: no devuelven nada, solo ejecutan acciones. - Métodos con tipo de retorno (
int,String, etc.): devuelven un valor que puede ser usado en otra parte del programa.
- Métodos
📌 Ejemplo:
int sumar(int a, int b) {
return a + b;
}🛡️ Modificadores de acceso
- Permiten controlar la visibilidad de clases, atributos y métodos:
public: accesible desde cualquier lugarprivate: solo accesible dentro de la misma claseprotected: accesible desde clases hijas o del mismo paquete
✅ Esto refuerza el principio de encapsulamiento, protegiendo la información sensible de un objeto.
📦 Palabras clave: static y final
static: asocia un atributo o método a la clase, no a sus objetos. Útil para valores globales o métodos utilitarios.final: indica que una variable, clase o método no puede ser modificada ni sobrescrita. Se usa para crear constantes o proteger comportamientos.
❓ ¿Qué es Optional?
Es una clase que permite manejar valores nulos de forma segura y evitar errores como NullPointerException.
En vez de retornar null, puedes retornar un Optional.empty() o un Optional.of(valor).
Esta sesión te ayudó a dominar la estructura base de cualquier programa en Java. Aprendiste a modelar el mundo real en código, usando clases como planos, objetos como instancias reales, y métodos como acciones que estos objetos pueden realizar. También comenzaste a aplicar buenas prácticas de diseño, protección de datos y organización del código.
Sesión 04. Elementos de una clase: implementa validación de datos
En esta sesión profundizaste en cómo estructurar correctamente una clase en Java, incluyendo no solo los atributos y métodos básicos, sino también elementos especiales que hacen que tus clases sean más eficientes, legibles y seguras. Aprendiste a utilizar constructores, métodos especiales, encapsulación, inmutabilidad y herramientas modernas como record y Objects.equals().
🧱 Constructores
- Ya conocías su función, pero aquí los exploraste en detalle:
- Constructor por defecto: no recibe parámetros y asigna valores predeterminados.
- Constructor con parámetros: permite crear objetos con valores personalizados.
- Constructor de copia: permite duplicar un objeto ya existente.
💡 También aprendiste sobre la sobrecarga de constructores, es decir, tener múltiples constructores con diferentes firmas en la misma clase.
🔁 Métodos especiales: equals(), hashCode() y toString()
- Estos métodos permiten que tus objetos sean más útiles cuando los comparas, los imprimes o los almacenas en estructuras como mapas o conjuntos.
| Método | ¿Para qué sirve? |
|---|---|
equals() |
Compara si dos objetos son equivalentes por su contenido, no por referencia. |
hashCode() |
Genera un código hash único para almacenar el objeto en estructuras como HashMap. |
toString() |
Devuelve una representación de texto del objeto, útil para mostrarlo por consola. |
✅ Buena práctica: cuando sobrescribes equals(), también debes sobrescribir hashCode() para evitar inconsistencias.
🔎 Objects.equals()
- Alternativa más segura a
equals(), ya que permite comparar objetos incluso si alguno es null, evitando errores.
📌 Ejemplo:
Objects.equals(obj1, obj2); // No lanza NullPointerException📦 record: clases inmutables simplificadas
- Una forma moderna y concisa de crear clases que solo almacenan datos.
- Java genera automáticamente el constructor,
equals(),hashCode()ytoString().
📌 Ejemplo:
record Usuario(String nombre, int edad) {}✅ Ideal para modelos de datos, DTOs o cualquier clase que solo requiera almacenar información.
🔒 Encapsulación e inmutabilidad
- Encapsulación: proteger los datos de una clase usando modificadores de acceso y métodos
getyset. - Inmutabilidad: crear objetos cuyos valores no cambian una vez creados. Se logra usando:
- Atributos
private final - Sin
setters - Inicialización por constructor
- Atributos
💡 Ventajas
- Protege la integridad del objeto.
- Evita errores inesperados en ejecución.
- Facilita la programación concurrente.
Esta sesión te mostró cómo construir clases sólidas, seguras y profesionales, cuidando los detalles de diseño que marcan la diferencia entre un código funcional y un código de calidad. También aprendiste herramientas modernas de Java que reducen el código repetitivo y aumentan la legibilidad.
Sesión 05. Diseño de clases (herencia y polimorfismo): reutiliza código existente por medio de herencia y polimorfismo
En esta sesión diste un gran paso en el dominio de la Programación Orientada a Objetos (POO), aprendiendo a estructurar clases de forma más eficiente y flexible. Estudiaste tres pilares fundamentales para crear código reutilizable, escalable y limpio: herencia, composición y polimorfismo.
🧬 Herencia
- Es el mecanismo que permite a una clase (subclase) heredar atributos y métodos de otra clase (superclase).
- Se implementa usando la palabra clave
extends. - Aporta reutilización de código, jerarquía lógica y menos duplicación.
📌 Ejemplo:
class Animal {
void hacerSonido() { System.out.println("Sonido genérico"); }
}
class Perro extends Animal {
@Override
void hacerSonido() { System.out.println("Ladrido"); }
}✅ Ventajas
- Permite centralizar comportamientos comunes.
- Facilita la extensión de funcionalidades.
🧩 Composición
- En lugar de heredar, una clase puede "tener" otras clases como atributos. Es decir, se construyen objetos más complejos a partir de otros.
- Favorece un diseño más modular y flexible.
- Es preferida sobre la herencia cuando no existe una clara relación "es un".
📌 Ejemplo:
class Motor {
void encender() { System.out.println("Motor encendido"); }
}
class Coche {
private Motor motor = new Motor();
void arrancar() {
motor.encender();
System.out.println("Coche en movimiento");
}
}💡 Regla de oro: Usa composición en relaciones "tiene un" y herencia solo cuando realmente hay una relación "es un".
🧠 Interfaces y clases abstractas
- Clases abstractas: no se pueden instanciar. Pueden contener métodos concretos y abstractos. Se heredan con
extends. - Interfaces: definen un contrato de métodos que una clase debe implementar. Se implementan con
implements.
✅ Las interfaces permiten simular herencia múltiple y mejorar la organización del código cuando hay funcionalidades comunes en clases no relacionadas.
📌 Ejemplo:
interface Transportador {
void transportarPasajeros();
}🔁 Polimorfismo
- Significa que un mismo método puede comportarse de manera diferente según el objeto que lo ejecute.
- Se implementa mediante la sobrescritura de métodos (
@Override).
📌 Ejemplo:
Animal miAnimal = new Perro();
miAnimal.hacerSonido(); // Imprime: "Ladrido"✅ El polimorfismo permite escribir código genérico, donde la lógica se adapta al tipo real del objeto en tiempo de ejecución.
Esta sesión te enseñó a estructurar mejor tus programas: usar herencia para aprovechar código existente, composición para diseñar sistemas modulares y polimorfismo para lograr flexibilidad. Aprendiste que escribir buen código no es solo hacerlo funcionar, sino también hacerlo extensible, organizado y mantenible.
Sesión 06. Colecciones: utiliza diversas estructuras de datos de acuerdo al tipo de aplicación a desarrollar
En esta sesión aprendiste a trabajar con estructuras de datos dinámicas en Java, fundamentales para manipular conjuntos de información de forma ordenada, eficiente y flexible. Descubriste cómo usar colecciones como listas, conjuntos y mapas, cuándo aplicarlas, y cómo ordenarlas según distintas necesidades.
📦 ¿Qué son las colecciones?
- Son estructuras que permiten agrupar y manejar múltiples datos como una sola unidad.
- Sustituyen a los arreglos cuando necesitas mayor flexibilidad (tamaño variable, operaciones de búsqueda, ordenamiento, etc.).
🔰 Tipos principales de colecciones
| Colección | Permite duplicados | Mantiene orden | Clave-Valor | Uso típico |
|---|---|---|---|---|
List |
✅ Sí | ✅ Sí | ❌ No | Lista de tareas, productos, etc. |
Set |
❌ No | ❌ No | ❌ No | Conjuntos únicos (como correos) |
Map |
✅ (en valores) | ✅ Sí | Diccionario, ID → nombre |
🧰 Estructuras comunes
ArrayList: lista ordenada que permite duplicados y acceso por índice.HashSet: conjunto sin duplicados, sin garantía de orden.HashMap: permite almacenar pares clave → valor, con claves únicas.
📌 Ejemplos:
ArrayList<String> nombres = new ArrayList<>();
HashSet<String> correos = new HashSet<>();
HashMap<Integer, String> empleados = new HashMap<>();🔢 Ordenamiento de colecciones
- Aprendiste dos formas de ordenar objetos, la primera:
Comparable(orden natural):- Se implementa en la clase.
- Solo permite un criterio de orden.
class Producto implements Comparable<Producto> {
public int compareTo(Producto otro) {
return this.precio - otro.precio;
}
}-
La segunda:
Comparator(orden personalizado):- Se define fuera de la clase.
- Permite múltiples criterios.
✅ Esto te permite organizar listas por precio, nombre, fecha, etc., según la necesidad.
🤯 Colecciones concurrentes Diseñadas para trabajo en múltiples hilos (multithreading). Evitan errores al acceder a colecciones desde distintos procesos simultáneamente.
Ejemplos:
CopyOnWriteArrayListConcurrentHashMap
💡 Útiles en aplicaciones con múltiples usuarios o tareas que ocurren al mismo tiempo.
En resumen, esta sesión te permitió dominar las estructuras dinámicas más usadas en Java, eligiendo la colección adecuada según si necesitas orden, unicidad o asociación clave-valor. También aprendiste a aplicar ordenamientos avanzados y preparar tus programas para trabajar en entornos concurrentes.
Sesión 07. Manejo de archivos: guarda información en un archivo de manera persistente
En esta sesión aprendiste a leer, escribir, copiar y mover archivos en Java de forma moderna, eficiente y segura usando la API NIO.2 (java.nio.file). Esta herramienta es esencial para desarrollar aplicaciones que interactúan con el sistema de archivos, como editores, cargadores de datos, reportes, logs y más.
📂 ¿Qué es NIO.2?
- Introducida en Java 7, mejora la antigua API de archivos (
java.io) ofreciendo:- Mayor flexibilidad
- Mejor rendimiento
- Soporte para operaciones concurrentes
- Manejo claro de rutas y excepciones
🧰 Clases clave de NIO.2
| Clase | ¿Para qué sirve? |
|---|---|
Path |
Representa una ruta de archivo o directorio |
Files |
Contiene métodos estáticos para operar sobre archivos y directorios |
FileSystems |
Permite acceder al sistema de archivos |
StandardWatchEventKinds |
Permite observar cambios en archivos/directorios |
📖 Lectura y escritura de archivos
Files.readString(): lee el contenido completo de un archivo como texto.Files.write(): escribe texto o datos binarios en un archivo.
📌 Ejemplo:
Path ruta = Path.of("notas.txt");
String contenido = Files.readString(ruta);
Files.write(ruta, "Nueva nota".getBytes());🔁 Copiar y mover archivos
Files.copy(origen, destino): duplica un archivo.Files.move(origen, destino): mueve o renombra un archivo. También puedes combinarlo con opciones comoStandardCopyOption.REPLACE\_EXISTING.
🧭 Verificación de archivos
Con métodos como:
Files.exists(path)Files.isReadable(path)Files.isWritable(path)Files.isDirectory(path)
Puedes validar rutas y permisos antes de realizar operaciones, lo cual previene errores y mejora la experiencia del usuario.
💡 Buenas prácticas al trabajar con archivos
- Verifica siempre que el archivo exista antes de leerlo o escribir sobre él.
- Usa rutas relativas para que tu programa sea más portable.
- Aplica
try-catchy estructuras comotry-with-resourcespara cerrar automáticamente recursos como archivos abiertos.
📌 Ejemplo:
try (BufferedReader reader = Files.newBufferedReader(path)) {
String linea;
while ((linea = reader.readLine()) != null) {
System.out.println(linea);
}
} catch (IOException e) {
e.printStackTrace();
}En resumen, esta sesión te permitió interactuar de forma profesional con el sistema de archivos, manejar documentos de entrada y salida, y escribir código más limpio, seguro y portable. Aprendiste a automatizar tareas comunes como guardar, copiar, mover y validar archivos usando el poder de Path y Files.
Sesión 08. Buenas prácticas y manejo de errores en Java
En esta última sesión técnica, diste un paso importante hacia la escritura de código profesional. Aprendiste a identificar problemas de diseño (code smells), aplicar principios de arquitectura (SOLID) y manejar errores de forma adecuada. Estos conocimientos te preparan para enfrentar proyectos reales con confianza y calidad.
✨ Refactorización y Code Smells
-
Refactorizar es reorganizar tu código sin cambiar su funcionalidad, con el objetivo de hacerlo más legible, modular y mantenible.
-
Identificaste code smells comunes:
- Código duplicado
- Funciones largas o con muchas responsabilidades
- Nombres poco claros
- Código comentado innecesario
✅ Solución: renombrar variables, extraer funciones, eliminar redundancias y aplicar el principio de responsabilidad única.
🧱 Principios SOLID Un conjunto de buenas prácticas orientadas a escribir código escalable y fácil de modificar:
| Principio | Descripción |
|---|---|
| S – Single Responsibility | Cada clase debe tener una única responsabilidad. |
| O – Open/Closed | El código debe estar abierto a extensión, pero cerrado a modificación. |
| L – Liskov Substitution | Las clases hijas deben poder sustituir a las clases padres sin romper la lógica. |
| I – Interface Segregation | Las interfaces deben ser específicas, no forzar a implementar métodos innecesarios. |
| D – Dependency Inversion* | Se deben usar abstracciones, no implementaciones concretas. |
📌 Aplicarlos mejora la calidad del código y reduce el riesgo de errores al hacer cambios.
⚙️ Optimización y rendimiento
- Elegir la estructura de datos adecuada: por ejemplo,
HashMappara búsquedas rápidas. - Dividir funciones largas y evitar bucles innecesarios.
- Reutilizar objetos y evitar asignaciones costosas.
- Cerrar recursos abiertos (archivos, conexiones) para evitar fugas de memoria.
- Las excepciones permiten reaccionar ante situaciones inesperadas (divisiones entre cero, archivos inexistentes, errores de entrada...).
- Java las clasifica en:
Checked(obligatorias de manejar): comoIOException.Unchecked(opcional de manejar): comoNullPointerException.
📌 Estructura:
try {
// Código que puede fallar
} catch (Exception e) {
// Código de manejo del error
} finally {
// Siempre se ejecuta
}✅ finally es ideal para liberar recursos (cerrar archivos, conexiones, etc.).
🚨 Excepciones personalizadas con throw y throws
throw: lanza manualmente una excepción.throws: declara que un método puede lanzar una excepción.
También aprendiste a crear tus propias excepciones para manejar reglas de negocio específicas:
📌 Ejemplo:
class EdadNoValidaException extends Exception {
public EdadNoValidaException(String mensaje) {
super(mensaje);
}
}Esta sesión cerró el ciclo técnico con herramientas que permiten escribir código de calidad: sólido, eficiente y preparado para lo inesperado. Aprendiste que un buen desarrollador no solo hace que el código funcione, sino que se asegure de que sea claro, seguro y fácil de mantener.
Durante estas nueve sesiones, recorriste un camino completo a través de los fundamentos y buenas prácticas del desarrollo en Java.
Desde configurar tu entorno, comprender la programación orientada a objetos, dominar estructuras de control y colecciones, hasta aplicar principios de diseño, manejar archivos y escribir código robusto frente a errores, has adquirido una base sólida para desarrollarte como programador Java. Has practicado cómo escribir código limpio, reutilizable y escalable. Aprendiste no solo a resolver problemas, sino a hacerlo con enfoque estructurado y profesional.
La Sesión 10 es una oportunidad para consolidar todos estos conocimientos, conectar ideas, identificar temas que requieran reforzamiento y aclarar cualquier duda.
Es un espacio para:
- Reforzar conceptos clave de todas las sesiones.
- Reconocer tu progreso.
- Compartir preguntas, experiencias y aprendizajes con tus compañeros.
- Prepararte para aplicar todo esto en proyectos reales.
Este recorrido no solo te enseñó Java: también te ayudó a desarrollar criterio técnico, pensamiento lógico, disciplina y confianza en tu proceso de aprendizaje.
Así que respira, repasa, reflexiona... ¡y prepárate para cerrar con fuerza este módulo! 🚀
⬅️ Anterior
