# ++**Proyecto Malla de juegos**++
**++Nombre:++**
el n-migos:
**++Integrantes:++**
Sebastian Aillapan
Orlando Caullan
Nicolas Toledo
John Fernandez
Julio Contreras
# Índice
1. Taller 1 - Inicio del proyecto
1.1 Descripción del Proyecto
1.2 Tecnologías
1.3 Priorización de Funcionalidades
1.4 Imagenes de Diagramas
2. Taller 2 - Calidad e inspección de codigo
1. Sección Grupal
1.1 Complejidad Ciclomática total
1.2 Complejidad Ciclomática por clase
1.3 Complejidad Ciclomática por método
1.4 Anáñisis de Acoplamiento con CBO
2. Sección Individual
2.1 Sebastian Aillapan - Análisis de Cohesión y Propuesta de Mejora
2.2 Orlando Caullan - Análisis de Cohesión y Propuesta de Mejora
2.3 Nicolas Toledo - Análisis de Cohesión y Propuesta de Mejora
2.4 John Fernandez - Análisis de Cohesión y Propuesta de Mejora
2.5 Julio Contreras - Análisis de Cohesión y Propuesta de Mejora
3. Tabla de evaluación
3. Taller 3 - Refactoring
1. Clase Catalogo (Code Smell: "Large Class")
1.1 Analisis
1.2 Pruebas Unitarias
1.3 Refactoring
2. Clase Perfil (Code Smell: "Speculative Generality")
2.1 Analisis
2.2 Pruebas Unitarias
2.3 Refactoring
3. Clase UsuarioNoRegistrado(Code Smell: "Lazy Class")
3.1 Analisis
3.2 Pruebas Unitarias
3.3 Refactoring
4. Link video
5. Link GitHub
6. Rubrica de Evaluación
# Taller 1 - Inicio del proyecto
## **++1.1 Descripción del Proyecto:++**
La Biblioteca o Malla de Juegos es una aplicación web que permite a los usuarios explorar y gestionar una colección de juegos clasificados por género y otros atributos. Los usuarios pueden buscar juegos, ver detalles, y gestionar sus propias preferencias, incluyendo la puntuación y las reseñas.
**++Idea inicial:++**
Aplicacion/web, Biblioteca de juegos organizados por genero y otro tipo de atributos
## **++1.2 Tecnologias:++**
-SpringBoot
-Front
## **++1.3 Priorizacion de funcionalidades:++**
++**Obligatorias:**++
1. Dentro del sistema se mostrara un catalogo de juegos por el cual el usuario podra:
-navegar por las secciones de juegos
-seleccionar un juego
2. El sistema tendra un apartado de busqueda de juegos la cual sera una barra visible desde la landing page que tendra opciones como:
-Busqueda por nombre
-Filtros predeterminados (categoria, año, etc)//por definir
3. El sistema permitira mostrar una ventana con descripcion de un juego con informacion como:
-Resumen del juego (titulo, genero, desarrollador, etc)
-Imagen
-Reseñas
-Calificacion
4. Los usuarios registrados podran obtener un juego desde su ventana de descripcion con la siguiente funcion:
-Añadir a biblioteca
5. El sistema tendra un registro de usuarios, este pedira datos como:
-Nombre (obligatorio)
-Contraseña (obligatorio)
-Generos de juego favorito (opcional)
6. Los usuarios (registrados) podran acceder a sus cuentas a travez de un login el cual les pedira:
-Nombre (obligatorio)
-contraseña (obligatorio)
7. Los usuarios (registrados) podran acceder a su perfil el cual mostrara los siguiente:
**informacion:**
-Nombre de usuario
-Generos favoritos de juego
**Opciones:**
-Ingresar a biblioteca personal
-Editar perfil
8. Cada usuario (registrado) tendra una biblioteca personal (a la que podran acceder desde perfil) en la cual puede gestionar juegos (contenidos en su biblioteca) con las siguientes funcionalidades:
-Puntuar un juego
-Dejar una reseña textual sobre un juego
-Eliminar una reseña textual hecha
-Agregar juegos a su biblioteca
-Agregar juegos a sus favoritos (ideal)
-Eliminar juegos de sus favoritos (ideal)
9. Los usuarios (registrados) podran editar su perfil desde una ventana especial con los siguientes campos:
-modificar nombre
-Agregar generos favoritos de juego
-Quitar generos favoritos de juego
++**Ideales:**++
1. El usuario tendra un apartado de juegos deseados el cual se puede modificar desde el perfil con las siguientes opciones:
-Agregar juegos a sus deseados
-Quitar juegos de sus deseados
2. El usuario puede proporcionar un correo electronico el cual sirve para:
-Recuperacion de contraseña
-Mensajes de ultimas novedades (spam)
3. El usuario (registrado) podra hacer un ranking top personal de sus juegos favoritos en el cual podra:
-agregar juegos de su biblioteca a al ranking (con un maximo de 10 juegos)
-seleccionar juegos para eliminarlos de el ranking
-subir de puesto un juego en el ranking
-bajar de puesto un juego en el ranking
4. El sistema debera poder recomendar un juego segun las preferencias del usuario (registrados) esto siempre y cuando este halla dejado puntuaciones y preferencias.
++**Fuera de alcance:**++
1. Abran usuarios con el rol de administrador que tendran permisos especiales de la pagina
2. Al ingresar al sistema se podra interactuar con un mini reproductor de musica
3. El sistema tendra una funcionalidad de compra y venta de juegos para usuarios logeados con las siguientes funcionalidades:
-Comprar un juego
-Vender un juego
-Intercambiar juegos con otro usuario
## ++**1.4 Imagenes de Diagramas**++
**Diagrama de Flujo**

**Diagrama de Casos de Uso**

# Taller 2-Calidad e Inspección de Código
## 2. Sección Grupal
### ++2.1 Complejidad Ciclomática Total++

""Resultado del análisis de la complejidad ciclomática total del proyecto.""
- La complejidad ciclomática del proyecto completo es de 69.
""Análisis del riesgo asociado""
Una complejidad ciclomática de 69 representa un riesgo considerable para el proyecto, afectando la mantenibilidad, la facilidad de prueba y la capacidad de evolución del software.
### ++2.2 Complejidad Ciclomática por Clase++

"" Resultado de la complejidad ciclomática por cada clase.""
- Para calcular la complejidad ciclomática por clase tenemos que dividir la complejidad ciclomática total por el numero de clases. Al hacer este calculo obtenemos que la complejidad por clase es de **7,6**.
"" Análisis del riesgo asociado para cada clase.""
- La clase con la deuda tecnica mas alta es la de catalogo con una deuda tecnica de una hora 50 minutos, la clase con el riesgo mas alto es la de usuarioRegistrado con un puntaje de c.
### ++2.3 Complejidad Ciclomática por Método++

"" Detalle de la complejidad ciclomática por método.""
- En este caso dividiremos la complejidad ciclomática total en la cantidad de metodos. La complejidad sería de **1,5** por método.
"" Riesgos asociados por métodos.""
- Con una complejidad ciclomática de 1,5 por metodo, los riesgos asociados a los metodos no son elevedados.Aun así pueden existir riesgos ocultos en los metodos mas extensos que se camuflan dentro de esta estadistica.
### ++2.4 Análisis de Acoplamiento con CBO++
"" Diagrama de clases y explicación del CBO de cada clase.""
- **Usuario:** La clase Usuario tiene una relación con la clase UsuarioNoRegistrado, ya que la flecha indica una relación de herencia
CBO:1
- **UsuarioNoRegistrado:** Hereda de Usuario, por lo que está acoplada a esta clase. Aparte de esta relación, no tiene interacciones con otras clases en el diagrama
CBO: 1
- **UsuarioRegistrado:** Está relacionada con la clase Usuario (herencia).
Interactúa directamente con la clase Juego a través de métodos como agregarJuegoBiblioteca(), eliminarJuegoBiblioteca() y puntuarydejarReseña().
También interactúa con Perfil (crea y edita).
Además, está relacionada con Biblioteca por medio de la gestión de juegos dentro de esta.
CBO: 4
- **Perfil:** UsuarioRegistrado (posee una referencia a un usuario registrado).
Biblioteca (posee una referencia a la biblioteca del usuario).
CBO: 2
- **Reseña:** UsuarioRegistrado, ya que cada reseña está vinculada a un usuario que la escribe.
Juego, dado que una reseña siempre pertenece a un juego específico.
CBO: 2
- **Biblioteca:** UsuarioRegistrado (en el contexto de gestionar los juegos que tiene un usuario en su biblioteca).
Juego (puesto que administra una colección de juegos).
CBO: 2
- **Catalogo:** Catalogo tiene una relación directa con Juego, ya que su propósito es almacenar una lista de juegos y permitir que estos se gestionen y se muestren.
CBO: 1
- **Juego:** Biblioteca (porque los juegos se guardan y eliminan de la biblioteca).
Catalogo (porque el catálogo muestra y gestiona los juegos).
Reseña (porque los juegos contienen reseñas).
UsuarioRegistrado (porque los usuarios registrados pueden puntuar o dejar reseñas en los juegos).
CBO: 4

"" Tipos de acoplamiento detectados: acoplamiento de datos, control, global, etc.""
- 1.Acoplamiento de datos: UsuarioRegistrado tiene métodos que interactúan con la clase Juego para agregar o eliminar juegos de la biblioteca (agregarJuegoBiblioteca(), eliminarJuegoBiblioteca()), lo que implica que se pasan instancias de Juego como parámetros. También sucede con Perfil, que almacena un UsuarioRegistrado y una Biblioteca
- 2.Acoplamiento de control: La clase UsuarioRegistrado utiliza métodos de Reseña como dejarReseña(), lo que sugiere que está dirigiendo el flujo de control hacia Reseña. Esto indica una dependencia en la secuencia de llamadas entre métodos.
## ++3. Sección Individual++
### 3.1 Sebastian Aillapan - Análisis de Cohesión y Propuesta de Mejora
#### 3.1.1 Análisis de Cohesión (LCOM4)
*Clase analizada: `Juego.java`
Resultado del análisis de cohesión (LCOM4):
Métodos de la clase Juego:
**getTitulo():** Accede a titulo.
**setCalificacion():** Accede a calificacion.
**agregarResena():** Accede a resenas.
**eliminarResena():** Accede a resenas.
**mostrarDetalles():** Accede a titulo, genero, desarrollador, calificacion, y imagen.
Grupo 1: Métodos que acceden a titulo: **getTitulo()** y **mostrarDetalles()**.
Grupo 2: Métodos que acceden a calificacion: **setCalificacion()** y **mostrarDetalles()**.
Grupo 3: Métodos que acceden a resenas: **agregarResena()** y **eliminarResena()**.
Grupo 4: El método **mostrarDetalles()** interactúa con varios atributos, pero no todos.
El valor de LCOM4 en este caso sería mayor que 1 debido a que tenemos varios subconjuntos de métodos que no interactúan entre sí, lo que indica que la cohesión de la clase es baja.
##### Tipos de cohesión detectados:
**Cohesión funcional:** Está presente en métodos como agregarResena() y eliminarResena(), que cumplen una tarea específica relacionada con la gestión de reseñas.
**Cohesión de control:** En los métodos que gestionan las reseñas, hay cierta dependencia del estado de la lista resenas.
**Cohesión lógica:** En métodos como mostrarDetalles(), donde se accede a múltiples atributos para mostrar la información del juego, se observa cierta cohesión lógica, pero podría mejorarse si este método gestionara más atributos.
### 3.1.2 Propuesta de Mejora de Acoplamiento
Clase analizada: `Juego.java`
#### Propuesta detallada de mejora para reducir el acoplamiento:
los puntos principales de acoplamiento son:
1.- Dependencia directa de la clase Reseña: La clase Juego tiene una lista de reseñas que están directamente acopladas a la clase Reseña.
2.- Dependencia directa de tipos específicos (como String, ArrayList): Aunque no es tan problemático como la dependencia de otras clases, aún puede mejorarse la flexibilidad del código.
**Propuesta:**
1) Reducir el acoplamiento con Reseña: Utilizando una interfaz como Resenable, logramos que Juego no dependa directamente de la implementación específica de Reseña. Esto permitirá que en el futuro se puedan utilizar otros tipos de reseñas sin modificar la clase Juego.
2) Mejorar la flexibilidad de las colecciones: Al usar la interfaz List en lugar de ArrayList, se reduce el acoplamiento con una implementación específica de la colección.
3) Opcional: Desacoplar la gestión de imágenes: Al usar una interfaz para gestionar cómo se obtienen las imágenes, se reduce el acoplamiento entre la clase Juego y cómo se maneja el almacenamiento de las imágenes.
#### 3.1.3 Propuesta de Mejora de Cohesión
Propuesta para mejorar la cohesión de la clase analizada (ClaseX.java).
### 3.2 Orlando Caullan - Análisis de Cohesión y Propuesta de Mejora
#### 3.2.1 Análisis de Cohesión (LCOM4)
**Clase analizada**: `Perfil.java`
#### Resultado del análisis de cohesión (LCOM4)
La métrica **LCOM4** indica que la clase `Perfil` tiene **alta cohesión**, ya que sus métodos interactúan con los mismos atributos (`usuario` y `biblioteca`). Esto sugiere que los métodos están bien relacionados con los datos de la clase.
Tipos de cohesión detectados:
- **Cohesión funcional**: Los métodos `mostrarInformacion()` y `editarInformacion()` están relacionados con los atributos `usuario` y `biblioteca`, mostrando un comportamiento cohesionado.
#### 3.2.2 Propuesta de Mejora de Acoplamiento (CBO)
**Clase analizada**: `Perfil.java`
Análisis del acoplamiento
La clase `Perfil` tiene un acoplamiento alto con las clases:
- `UsuarioRegistrado`
- `Biblioteca`
Problema detectado:
- La clase depende directamente de los detalles de implementación de `UsuarioRegistrado` y `Biblioteca`, lo que aumenta su acoplamiento y puede generar problemas de mantenimiento si estas clases cambian en el futuro.
Propuesta detallada de mejora para reducir el acoplamiento:
- Utilizar **Inyección de Dependencias** para evitar que `Perfil` dependa directamente de `UsuarioRegistrado` y `Biblioteca`.
- Implementar **abstracciones** para reducir la dependencia de clases concretas, favoreciendo el uso de interfaces u otras soluciones que desacoplen las dependencias.
#### 3.2.3 Propuesta de Mejora de Cohesión (LCOM4)
**Clase analizada**: `Perfil.java`
Análisis de la cohesión actual:
La clase `Perfil` tiene buena cohesión actualmente, ya que sus métodos (`mostrarInformacion()` y `editarInformacion()`) acceden a los mismos atributos (`usuario` y `biblioteca`).
Propuesta para mejorar la cohesión:
- En el caso de que se añadan más métodos que operen exclusivamente sobre uno de los atributos (`usuario` o `biblioteca`), se recomienda dividir la clase en dos clases más especializadas. Esto garantizaría que cada clase mantenga una cohesión alta al interactuar con un conjunto común de atributos.
### 3.3 Nicolas Toledo - Análisis de Cohesión y Propuesta de Mejora
#### 3.3.1 Análisis de Cohesión (LCOM4)
Clase analizada: UsuarioRegistrado.java
Resultado del análisis de cohesión (LCOM4):
- La clase UsuarioRegistrado tiene una cohesión de 3 lo que indica que esta clase esta haciendo demasiadas cosas distintas.
Metodos de que interactuan con biblioteca

Metodos que interactuan con Juego

Tipos de cohesión detectados:
- 1. Grupo Manejo de la sesión:
**Metodos:** iniciarSesion()
**Atributos:** nombre, contraseña
**Desc:** Este grupo tiene cohesión funcional porque está enfocado en una sola funcionalidad.
- 2. Grupo Gestión de la biblioteca:
**Metodos:** getBiblioteca(), agregarJuegoBiblioteca(), eliminarJuegoBiblioteca(), buscarJuegoPorNombre(), filtrarJuegos().
**Atributos:** biblioteca
**Desc:** Este grupo presenta una cohesión de comunicación, ya que los metodos no dependen entre si pero trabajan con los mismos datos.
- 3. Grupo Gestión de reseñas y puntuaciones:
**Metodos:** puntuarJuego(), dejarResena(), eliminarResena().
**Atributos:** Ningún atributo propio de la clase, interactuan con un objeto Juego y reseña.
**Desc:** Este grupo tiene cohesión funcional porque todos los métodos están relacionados con la funcionalidad de gestión de reseñas y puntuación de los juegos.
#### 3.3.2 Propuesta de Mejora de Acoplamiento (CBO)
Clase analizada: UsuarioRegistrado.java
- Al reubicar los metodos de biblioteca y reseña que no corresponden a esta clase disminuira el acoplamiento de esta clase.
#### 3.3.3 Propuesta de Mejora de Cohesión (LCOM4)
- Se propone separar las responsabilidades que tiene la clase de usuarioRegistrado.Los metodos que interactuan con la clase biblioteca pasaran a estar dentro de biblioteca, lo mismo con los metodos de reseña que pasar a estar en la clase reseña, al dividir estos metodos las tres clases que quedaran tendran un LCOM4 de 1 y una cohesión funcional.
### 3.4 John Fernandez - Análisis de Cohesión y Propuesta de Mejora
#### 3.4.1 Análisis de Cohesión (LCOM4)
**Clase analizada:**
`Resena.java`


#### Resultado del análisis de cohesión (LCOM4):
en la clase existen 3 componentes distintos:
1) incluye solo el método **getUsuario()**.
2) incluye los métodos que acceden a eliminada(**getTexto(),editarTexto(),eliminar(), esEliminada()**).
3) incluye solo el método **getFechaCreacion()**
en resumen el LCOM4 de la clase Resena es 3, lo que significa que la cohesión de la clase es moderada a baja,lo que indica que hay espacio para mejorar la organización interna de la clase, haciendo que los métodos trabajen más en cojunto o asignando responsabilidades a otras clases.
#### Tipos de cohesión detectados:
**1.- Cohesión Funcional:**
los métodos **eliminar()** y **esEliminada()** trabajan en conjunto para manejar el estado de la reseña eliminada. Esto sugiere que estan cohesionados funcionalmente, ya que su propósito es gestionar el mismo aspecto de la clase.
**2.- Cohesión Temporal:**
aparece en el constructor de la clase, ya inicializa los atributos **usuario**,**texto**,**fechaCreacion**, y **eliminada** al mismo tiempo cuando se crea una nueva instancia de la clase.
**3.- Cohesión Lógica:**
**getUsuario** y **getTexto()** no comparten atributos, pero estan cohesionados lógicamente porque ambos son aspectos importantes de una reseña.
#### 3.4.2 Propuesta de Mejora de Acoplamiento (CBO)
Clase analizada: `Resena.java`
Propuesta detallada de mejora para reducir el acoplamiento:
1) Se podria desacoplar **Resena** de **UsuarioRegistrado** y utilizar una interfaz Usuario par aque la Resena no dependa directamente de UsuarioRegistrado.
Ejemplo:

2) También podríamos desacoplar **Resena** de **Juego** y usar una interfaz Contenido Reseñable para que Resena pueda aceptar Cualquier contenido de Juego u otras clases que puedan ser necesarias a futuro.
Ejemplo:

Estas mejoras harán que el codigo sea más flexible, modular y menos propenso a errores si alguna de las clases cambien en el futuro, cumpliendo con el objetivo de reducir los riesgos y el acoplamiento.
#### 3.4.3 Propuesta de Mejora de Cohesión (LCOM4)
Las propuestas de mejora para la cohesión de la clase Reseña incluyen:
la edición del texto y la fecha de edición en un método más completo (actualizarResena()).
Añadir un método para restaurar reseñas eliminadas, permitiendo una gestión más completa del estado de eliminación.
Agregar un método mostrarDetalles() para devolver todos los detalles relevantes de la reseña en un solo lugar.
Centralizar la validación del texto en un método privado, mejorando la cohesión lógica.
Estas mejoras harán que la clase Reseña sea más cohesiva y organizada, ya que los métodos estarán más relacionados entre sí y con los atributos que gestionan.
### 3.5 Julio Contreras - Análisis de Cohesión y Propuesta de Mejora
#### 3.5.1 Análisis de Cohesión (LCOM4)
Clase analizada: [Catalogo].java

##### Resultado del análisis de cohesión (LCOM4):
El análisis de cohesión en la clase Catalogo muestra que los métodos dentro de la clase tienen responsabilidades diversas en concreto hay dos tipos de componentes:
1.- Métodos que manejan la lista de juegos (ingresarJuego, mostrarCatalogo).
2.- Metodos que se encargan de la interacción con la API (conseguirIDs, conseguirJuegos).
En resumen el LCOM4 de la clase es de 2 y sus funciones son manejar tanto la lógica de administración de juegos como la comunicación con la API.
##### Tipos de cohesión detectados:
**1.- Cohesión Funcional:**
Algunos métodos como ingresarJuego() y mostrarCatalogo() están cohesionados, ya que todos trabajan directamente con la lista de juegos.
**2.-Cohesión lógica:**
Los métodos que interactúan con la API (conseguirIDs() y conseguirJuegos()) dependen de parámetros como las URLs y las respuestas HTTP, pero no están directamente relacionados con la administración interna de los juegos.
#### 3.5.2 Propuesta de Mejora de Acoplamiento (CBO):
Clase analizada: [Catalogo].java
**1.- Separación de responsabilidades:**
Se propone dividir la responsabilidad de la clase en dos partes: una para manejar el catálogo de juegos y otra para la comunicación con la API. De esta manera, se reduce el acoplamiento directo de la clase Catalogo con elementos externos como HttpURLConnection y JSONObject, delegando la comunicación con la API a una clase externa que se encargue de estos detalles.
**2.- Inyección de dependencias:**
Introducir una instancia externa para el servicio API mediante inyección de dependencias. Esto permite desacoplar la clase Catalogo de los detalles de implementación de la API.
#### 3.5.3 Propuesta de Mejora de Cohesión (LCOM4)
**Propuesta:**
Dividir la clase Catalogo en dos clases con responsabilidades claras: una clase encargada de gestionar el catálogo de juegos (administración, visualización) y otra clase que maneje la comunicación con la API externa. Esto aumenta la cohesión funcional de cada clase, ya que cada una tendrá una responsabilidad única y bien definida.
Al separar las funcionalidades relacionadas con la API, se logra que la clase Catalogo solo maneje la lógica de los juegos, lo que incrementa la cohesión y facilita el mantenimiento y la extensibilidad del código.
## Tabla de evaluación

# Taller 3 - Refactoring
## 1. Clase Catalogo (Code Smell: "Large Class")
### 1.1 Analisis
**Code Smell detectados:** Long Method y Large Class
**Técnica de Refactoring:** Extract Class
**++Contexto++**
La clase "Catalogo" es muy larga, tiene 2 métodos (con más de 30 líneas cada 1) que se pueden dividir en métodos más pequeños, sin embargo el code smell “long method”, puede resolverse de paso al aplicar “Extract Class” y crear una clase la cual gestione de mejor manera estos 2 métodos (y de paso aplicar “extract method”) los cuales cumplen dos funciones a la vez.
**++Clase Catalogo pre-Refactoring:++**

**Solucion Propuesta:** La clase se va a separar en 3, una para crear y gestionar catálogo, otra para las funcionalidades que recopilan información de la api y la ultima que creara los juegos del catálogo a partir de los datos recopilados de la clase anterior.
---
### 1.2 Pruebas Unitarias
Las pruebas unitarias hechas para "Catalogo" fueron generadas con ia tomando en cuenta que esta clase se va a refactorizar más adelante y las pruebas se tienen que mantener para las funcionalidades de catalogo, los métodos a testear y los cuales después del refactoring deberían de funcionar como antes son los siguientes:

**++Consideraciones dentro de las PU:++**
1. Debido a la separación de clases, las pruebas unitarias irreparablemente tendrán que cambiar su sintaxis, sin embargo se van a testear las mismas 4 funcionalidades principales intentado cambiar solo las instancias a la clase "Catalogo" por la clase necesaria.
2. El método mostrarCatalogo no modifica ni devuelve nada dentro del código por lo que en este caso se omitió dentro de las pruebas para poder mostrar su funcionamiento por consola en el video.
**++Peticion de pruebas unitarias a IA++**
Después de definir los métodos importantes que mantienen la integridad de las funcionalidades de catálogo se le pidió el siguiente prompt a Chat Gpt:
*“Quiero que me ayudes a hacer pruebas unitarias para una clase hecha en Java, siguiendo la rúbrica que te proporcione, a la clase en cuestión se le aplicará un refactoring ya que esta presenta el code smell "large class", esto porque la clase llamada catálogo maneja 3 tareas las cuales pueden dividirse en más clases, lo que se hará será lo siguiente: La clase se va a separar en 3, una para crear y gestionar catálogo, otras para las funcionalidades que recopilan información de la api y las que crean los juegos del catálogo. Ten en cuenta que las pruebas unitarias deben de estar diseñadas para que funciones antes y después del refactoring, aunque sea prácticamente imposible mantener las pruebas 100% estáticas después del cambio que resulta separar una clase, quiero que crees las pruebas unitarias para que se parezcan lo más posible a su versión pre-refactoring.”*
Al entregarle la rúbrica de evaluación y la clase a refactorizar las pruebas generadas fueron las siguientes:
class CatalogoTest {
private Catalogo catalogo;
@BeforeEach
void setUp() {
catalogo = new Catalogo();
}
@Test
void testIngresarJuego() {
Juego juego = new Juego("Titulo1", "2022", "Accion", "Desarrollador1", "url_imagen", "Descripción breve");
catalogo.ingresarJuego(juego);
assertEquals(1, catalogo.getListaJuegos().size());
assertEquals("Titulo1", catalogo.getListaJuegos().get(0).getTitulo());
}
@Test
void testIngresarID() {
catalogo.ingresarID(123);
catalogo.ingresarID(123); // Intentamos agregar la misma ID otra vez
assertEquals(1, catalogo.gameIDs.size()); // La ID no debe duplicarse
}
@Test
void testConseguirIDs() {
// Simulamos la obtención de IDs de la API
catalogo.conseguirIDs();
assertFalse(catalogo.gameIDs.isEmpty()); // Verificamos que la lista de IDs no esté vacía después de la llamada
}
@Test
void testConseguirJuegos() {
// Primero agregamos algunas IDs
catalogo.ingresarID(1);
catalogo.ingresarID(2);
// Ejecutamos el método para conseguir los juegos
catalogo.conseguirJuegos();
// Verificamos que los juegos fueron añadidos
assertFalse(catalogo.getListaJuegos().isEmpty());
}
}
**++Conclusion de la PU:++** Las pruebas obtenidas de la ia resultaron ser adecuadas a nuestro criterio para asegurar que el proceso de refactoring sea bien implementado y que no cambie el funcionamiento del catalogo, despues del refactoring lo unico que se cambio en las pruebas fue una instancia adicional de "CreadorJuegos" que contiene los metodos "ingresarID" y "getGameIDs", El uso de la ia fue beneficioso pero no crucial pues desde un principio ya se definio los puntos a testear y mantener en el funcionamiento de catalogo.
---
### 1.3 refactoring
**++Resumen:++**
Se aplico la tecnica de refactoring **"Extract Class"**, separando la clase catalogo en 3:
1. Catalogo: Clase encargada de gestionar el catalogo de juegos
2. CreadorJuegos: Clase encargada de crear instancias de juego
3. Clase encargada de extraer datos sobre juegos desde una api
**++Resultados++**
El funcionamiento del catalogo siguio tal cual antes y despues del refactoring con la excepcion del metodo ++"conseguirIDs"++ que paso de estar en "Catalogo" a "CreadorJuegos", necesitando una llamada de atributo mas:
Catalogo.conseguirIDs(); ---> catalogo.getCreadorJuegos().conseguirIDs();
Despues de aplicar **"Extract Class** este es el resultado":
---
**++Catalogo:++**

---
**++CreadorJuegos:++**

---
**++ConsultorApi:++**

---
**++Conclusion del refactoring:++**
Ahora la clase Catalogo cumple unicamente su funcion dejando las otras funcionalidades a otras clases, mejorando la cohesion de esta.
durante el proceso pre y post refactoring la salida no cambio:
++uso del catalogo++
//pruebas catalogo post-refactoring
Catalogo catalogo = new Catalogo();
catalogo.mostrarCatalogo();
catalogo.conseguirJuegos();
catalogo.getCreadorJuegos().conseguirIDs();
catalogo.conseguirJuegos();
catalogo.mostrarCatalogo();
//pruebas catalogo pre-refactoring
CatalogoPreR preCatalogo = new CatalogoPreR();
preCatalogo.mostrarCatalogo();
preCatalogo.conseguirJuegos();
preCatalogo.conseguirIDs();
preCatalogo.conseguirJuegos();
preCatalogo.mostrarCatalogo();
++salida (ambos casos):++
El catálogo está vacío de momento
Primero se tienen que ingresar las ID al catálogo
IDs conseguidas
Se añadió el juego 'Grand Theft Auto V' al catálogo
Se añadió el juego 'The Witcher 3: Wild Hunt' al catálogo
Se añadió el juego 'Portal 2' al catálogo
Se añadió el juego 'Counter-Strike: Global Offensive' al catálogo
Se añadió el juego 'Tomb Raider (2013)' al catálogo
Se añadió el juego 'Portal' al catálogo
Se añadió el juego 'Left 4 Dead 2' al catálogo
Se añadió el juego 'The Elder Scrolls V: Skyrim' al catálogo
Se añadió el juego 'Red Dead Redemption 2' al catálogo
Se añadió el juego 'BioShock Infinite' al catálogo
-----------------------------------------------------------------------------------------
Título: Grand Theft Auto V
Género: Action
Desarrollador: Rockstar North, Rockstar Games
Calificación: 0.0
Url de Imagen: https://media.rawg.io/media/games/20a/20aa03a10cda45239fe22d035c0ebe64.jpg
-----------------------------------------------------------------------------------------
Título: The Witcher 3: Wild Hunt
Género: Action, RPG
Desarrollador: CD PROJEKT RED
Calificación: 0.0
Url de Imagen: https://media.rawg.io/media/games/618/618c2031a07bbff6b4f611f10b6bcdbc.jpg
-----------------------------------------------------------------------------------------
Título: Portal 2
Género: Shooter, Puzzle
Desarrollador: Valve Software
Calificación: 0.0
Url de Imagen: https://media.rawg.io/media/games/2ba/2bac0e87cf45e5b508f227d281c9252a.jpg
-----------------------------------------------------------------------------------------
Título: Counter-Strike: Global Offensive
Género: Shooter
Desarrollador: Valve Software, Hidden Path Entertainment
Calificación: 0.0
Url de Imagen: https://media.rawg.io/media/games/736/73619bd336c894d6941d926bfd563946.jpg
-----------------------------------------------------------------------------------------
Título: Tomb Raider (2013)
Género: Action, Fighting
Desarrollador: Crystal Dynamics
Calificación: 0.0
Url de Imagen: https://media.rawg.io/media/games/021/021c4e21a1824d2526f925eff6324653.jpg
-----------------------------------------------------------------------------------------
Título: Portal
Género: Action, Puzzle
Desarrollador: Valve Software, NVIDIA Lightspeed Studios
Calificación: 0.0
Url de Imagen: https://media.rawg.io/media/games/7fa/7fa0b586293c5861ee32490e953a4996.jpg
-----------------------------------------------------------------------------------------
Título: Left 4 Dead 2
Género: Action, Shooter
Desarrollador: Valve Software, Turtle Rock Studios
Calificación: 0.0
Url de Imagen: https://media.rawg.io/media/games/d58/d588947d4286e7b5e0e12e1bea7d9844.jpg
-----------------------------------------------------------------------------------------
Título: The Elder Scrolls V: Skyrim
Género: Action, RPG
Desarrollador: Bethesda Game Studios
Calificación: 0.0
Url de Imagen: https://media.rawg.io/media/games/7cf/7cfc9220b401b7a300e409e539c9afd5.jpg
-----------------------------------------------------------------------------------------
Título: Red Dead Redemption 2
Género: Action
Desarrollador: Rockstar Games
Calificación: 0.0
Url de Imagen: https://media.rawg.io/media/games/511/5118aff5091cb3efec399c808f8c598f.jpg
-----------------------------------------------------------------------------------------
Título: BioShock Infinite
Género: Action, Shooter
Desarrollador: Aspyr Media, 2K Australia, Irrational Games
Calificación: 0.0
Url de Imagen: https://media.rawg.io/media/games/fc1/fc1307a2774506b5bd65d7e8424664a7.jpg
---
## 2. Clase Perfil (Code Smell: "Speculative Generality")
### 2.1 Analisis
**Code Smell detectados:** Speculative Generality
**Técnica de Refactoring:** Inline Class, Remove Parameter
++Contexto++
La clase ++"Perfil"++ en su primera version contenia un atributo de biblioteca que no se usaba en el codigo actual, lo cual indica que tiene un "Speculative Generality" esto suele ocurrir cuando un atributo o clase anticipa una necesidad que no existe.
Para resolver estos problemas, se aplicaron las siguientes técnicas de refactorización:
++**Inline Class:**++ Esta tecnica se utilizo para simplificar la clase, eliminando la referencia innecesaria a ++"Biblioteca"++ ya que no se requeria para la funcion actual de ++"Perfil"++. Al quitarla, la clase se centro en su proposito principal, que es representar la informacion de++"UsuarioRegistrado"++, reduciendo asi el acoplamiento y mejorando la cohesion.
++**Remove Parameter:**++ Tambien aplicamos Remove Parameter. Esta simplificacion elimino metodo adicional, haciendo que la clase fuera más directa y ligera, sin metodos necesario que no aportaban valor a su funcionalidad.
++**Clase Perfil pre-Refactoring:**++

**Solucion Propuesta:** La solucion es eliminar la clase biblioteca que se genera dentro de perfil ya que esta como una clase innecesaria y eliminar el metodo de editarInformacion().
### 2.2 Pruebas Unitarias
Las pruebas unitarias fueron creadas por nuestra cuenta en la cual un test consiste en la creacion de la clase perfil y otro test para ver el metodo mostrar informacion con un assert si coicide que el usuario que se le entrego.
```
package org.example;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class PerfilTest {
private Perfil perfil;
private UsuarioRegistrado usuario;
private final ByteArrayOutputStream ContenidoSystem = new ByteArrayOutputStream();
@BeforeEach
void setUP(){
usuario = new UsuarioRegistrado(1,"juanito", "22123");
System.setOut(new PrintStream(ContenidoSystem));
}
@Test
void CrearPerfil() {
Perfil perfil = new Perfil(usuario);
assertNotNull(perfil, "La clase perfil no fue creada correctamente");
}
@Test
void MostrarInformacion(){
Perfil perfil = new Perfil(usuario);
perfil.mostrarInformacion();
String MostratUsuario = "Mostrando información del perfil del usuario: " + usuario.toString() + System.lineSeparator();
assertEquals(MostratUsuario, ContenidoSystem.toString());
}
}
```
++**Comprobacion de funcionamiento:**++

### 2.3 Refactoring
++**Resumen:**++
Se aplicaron las tecnicas de refactoring **"Inline Class"** a la clase biblioteca y **"Remove Parameter"** al metodo de editarInformacion().
**++Resultados++**
Después de aplicar los cambios la clase quedo de esta manera:

Para comprobar que sigue funcionando tenemos los resultado de las pruebas unitarias:

**++Conclusion del refactoring:++**
Después de refactorizar la clase perfil se logro una clase más limpia sin metodos adicionales que molestara la clase cumpliendo unicamente su funcion.
## 3. Clase UsuarioNoRegistrado(Code Smell: "Lazy Class")
### 3.1 Análisis
**Code Smell detectado:** Lazy Class
**Técnica de Refactoring:** Inline Class
**++Contexto++**
La clase UsuarioNoRegistrado no cumple ninguna función en especifico, sus métodos son solo prints de mensajes y además esta clase no era usada nunca en la aplicación.
**++Clase UsuarioNoRegistrado pre-Refactoring:++**

**++Clase UsuarioRegistrado pre-Refactoring:++**




**Solucion propuesta:** Al aplicar la técnica de refactoring inline class, UsuarioNoRegistrado puede quedar como un parámetro booleano en usuarioRegistrado donde el parametro es true si el usuario esta registrado y false si el usuario no esta registrado.
### 3.2 Pruebas Unitarias
Las pruebas se generaron para la clase usuarioRegistrado para chequar que al agregar el parámetro que remplaza a la clase UsuarioNoRegistrado este no afecte el funcionamiento de la clase.
```
package org.example;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import static org.junit.jupiter.api.Assertions.*;
class UsuarioRegistradoTest {
static UsuarioRegistrado usuarioRegistrado;
static Juego juegoTest;
@BeforeAll
static void setUpBeforeClass(){
usuarioRegistrado = new UsuarioRegistrado(1,"Test","123");
juegoTest = new Juego("Titulo1", "2022", "Accion", "Desarrollador1", "url_imagen", "Descripción breve");
}
@Test
void testIniciarSesion() {
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
System.setOut(new PrintStream(outContent));
usuarioRegistrado.iniciarSesion("123");
assertEquals("Iniciando sesión para el usuario: Test\r\n",outContent.toString());
System.setOut(System.out);
}
@Test
void testIniciarSesionClaveIncorrecta() {
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
System.setOut(new PrintStream(outContent));
usuarioRegistrado.iniciarSesion("1234");
assertEquals("contrasena no valida",outContent.toString());
System.setOut(System.out);
}
@Test
void testAgregarJuegoBiblioteca() {
usuarioRegistrado.agregarJuegoBiblioteca(juegoTest);
assertFalse(usuarioRegistrado.getBiblioteca().getJuegos().isEmpty());
}
@Test
void testEliminarJuegoBiblioteca() {
usuarioRegistrado.eliminarJuegoBiblioteca(juegoTest);
assertTrue(usuarioRegistrado.getBiblioteca().getJuegos().isEmpty());
}
@Test
void testDejarResena(){
usuarioRegistrado.dejarResena(juegoTest,"Resena Test");
assertFalse(juegoTest.getResenas().isEmpty());
}
@Test
void testDejarResenaVacia(){
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
() -> usuarioRegistrado.dejarResena(juegoTest, "")
);
assertEquals("El texto de la reseña no puede estar vacío.", exception.getMessage());
}
@Test
void testEliminarResena(){
usuarioRegistrado.eliminarResena(juegoTest,juegoTest.getResenas().get(0));
assertTrue(juegoTest.getResenas().isEmpty());
}
@Test
void testPuntuarJuego(){
usuarioRegistrado.puntuarJuego(juegoTest,1);
assertEquals(1,juegoTest.getCalificacion());
}
}
```
### 3.3 Refactoring
#### Pre-Refactoring:
La clase UsuarioNoRegistrado extiende de Usuario para representar a usuarios que aún no se han registrado. Esta clase incluye métodos específicos como registrar() e iniciarComoInvitado(), pero su funcionalidad se limita a operaciones muy básicas que no aprovechan realmente el beneficio de una jerarquía de clases. Esto incrementa la complejidad del código, pues se deben gestionar dos tipos de usuarios, UsuarioRegistrado y UsuarioNoRegistrado, aunque el comportamiento es en gran medida similar.
#### Refactorig:
Para simplificar y refactorizar nuestra clase UsuarioNoRegistrado, es conveniente eliminarla y trasladar su funcionalidad a la clase UsuarioRegistrado usando un atributo booleano, por ejemplo, estaRegistrado. Esto eliminará la necesidad de una jerarquía separada para los usuarios no registrados y reducirá el código duplicado.
##### 1.- Identificamos en qué clases o métodos se utiliza UsuarioNoRegistrado:
En nuestro caso ninguna clase está ocupando ni referenciando a la clase UsuarioNoRegistrado solo a usuarioRegistrado.
##### 2.- Evaluar el Propósito del código dentro de UsuarioNoRegistrado:
luego de la inspección de código cruzada que podríamos integrar directamente en otra clase o manejarse con una clase Usuario genérica.
pero como existe la clase UsuarioRegistrado es mejor integrar a esta clase los métodos o funciones pensadas en UsuarioNoRegistrado.
Y mover cualquier validación específica o lógica de UsuarioNoRegistrado si es necesario.
#### Cambios principales:
##### 1.- Clase UsuarioRegistrado:
• Agregamos el constructor y el metodo estaRegistrado, el cual usamos para condicionar el acceso a métodos.
• Cada método restringido verifica estaRegistrado y responde si el usuario no tiene permisos.
##### 2.- Clase UsuarioNoRegistrado:
• Clase completa eliminada
#### Post-Refactoring:
Se elimina la clase UsuarioNoRegistrado y se integra su funcionalidad directamente en la clase UsuarioRegistrado mediante un atributo booleano (esRegistrado). Con este enfoque, un usuario puede estar registrado o no dependiendo del valor de este atributo, y todos los métodos están en una sola clase, simplificando la jerarquía y reduciendo el código repetitivo. Este refactoring mejora la legibilidad y facilita el mantenimiento, ya que ahora se gestiona solo una clase. Se elimina la clase UsuarioNoRegistrado y se integra su funcionalidad directamente en la clase UsuarioRegistrado mediante un atributo booleano (esRegistrado). Con este enfoque, un usuario puede estar registrado o no dependiendo del valor de este atributo, y todos los métodos están en una sola clase, simplificando la jerarquía y reduciendo el código repetitivo. Este refactor mejora la legibilidad y facilita el mantenimiento, ya que ahora se gestiona solo una clase.
#### Pruebas Unitarias:
Las pruebas unitarias siguen funcionando sin problemas:

---
## Link del video:
https://drive.google.com/drive/folders/1eZGSWbrvRxL-hWZQwbZ65e68zgmy2l1X?usp=sharing
---
## Link del GitHub:
https://github.com/ElCuervas/n-migos.java
---
## Rubrica de evaluacion:
