AgustinTroncoso
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Reporte de Proyecto: Módulo de Carrito y Compras - Avance 2 ## 1. Declaración Inicial del Módulo ### i. Nombre de Equipo e Integrantes - **Nombre del Equipo:** Carrito y Compras - **Integrantes:** - Elías Currihuil - Agustín Troncoso ## 1.1 Estructura de Proyecto: Implementación del Patrón MVC y Capa de Repositorios Dentro del marco de mejoras continuas, se ha reestructurado el proyecto para adoptar prácticas reconocidas en diseño y arquitectura de software. ### Patrón Modelo-Vista-Controlador (MVC) El proyecto ha integrado el patrón **MVC**, que separa responsabilidades en: - **Modelo**: Gestiona datos y lógica de negocio. - **Vista**: Presenta información al usuario a través de interfaces. - **Controlador**: Coordina la interacción entre Modelo y Vista. La adopción de este patrón facilita la modularidad y mantenibilidad del software. ### Capa de Repositorios Se ha añadido una **capa de repositorios** para gestionar la interacción con las fuentes de datos. Aunque el actual almacenamiento se basa en archivos JSON en el directorio `test-api`. Debido a lo anterior, actualmente los registros del sistema son estáticos y no se pueden modificar, pero se espera que en la siguiente entrega, y con la futura conexión a una fuente de almacenamiento de datos, su implementación sea la adecuada. Resumiendo, esta capa permite una estructurada deserialización y presentación de datos a los controladores. Esta estrategia posiciona al proyecto para futuras adaptaciones en el almacenamiento de datos. ## 2. Entidades Principales y Flujo de Datos ## Flujo de Datos y Estructura de Entidades Es esencial destacar que las acciones principales realizadas con cada entidad dentro del flujo de datos de la aplicación, se gestionan a través de un `Controller` y un `Repository` asociados. Estos componentes manejan la lógica de negocio y las transacciones con los sistemas de almacenamiento de datos. Las entidades actúan como un componente clave para la transacción de datos entre las diferentes capas de abstracción del sistema. ## Entidades Principales La aplicación cuenta con una serie de entidades o modelos clave, que residen en el paquete `models`. Estas entidades definen la estructura y el flujo de datos de la app. A continuación, se presenta en detalle la entidad `Product`. ### Product La entidad `Product` es la encargada de representar los productos, en este caso, los juegos, dentro de la aplicación. Esta entidad juega un papel crucial en el flujo de datos, utilizando inicialmente al `ProductController`, que a su vez interactúa con el `ProductRepository` para gestionar las transacciones de datos en el sistema. Sus principales atributos son: - **id (int)**: Identificador único del producto. - **name (String)**: Nombre del juego. - **price (double)**: Precio del juego. - **publisher (String)**: Editorial o empresa que publica el juego. - **release (String)**: Fecha de lanzamiento. - **categories (List<Category>)**: Lista de categorías a las que pertenece el juego. Esta lista está vinculada a un Enum `Category`, que define las posibles categorías a las que un juego puede ser asociado. - **developer (String)**: Nombre del desarrollador. - **stockQuantity (int)**: Cantidad disponible en stock. #### Nota sobre el atributo `developer`: Actualmente, el atributo `developer` se maneja como un `String`. Sin embargo, esto es una medida temporal. En futuras iteraciones, y con la integración de las instancias de usuario, se espera cambiar este atributo a una ID de Developer. De esta manera, se garantiza que cada producto pertenezca a un único desarrollador, proporcionando robustez y coherencia a la estructura. ### Cart La entidad `Cart` representa el carrito de compras de un usuario en la aplicación, gestionado a través del `CartController`. Dada su naturaleza, se crea en tiempo de ejecución y no tiene una representación persistente a través de un `Repository` ya que se almacena en conjunto con la orden. Sus atributos principales son: - **cartItems (List<CartItem>)**: Esta lista representa los artículos dentro del carrito. Cada `CartItem` tiene un producto asociado y una cantidad (representada por el atributo `int quantity`). ### DiscountCode `DiscountCode` es la entidad responsable de representar los códigos de descuento en la aplicación. Esta entidad juega un papel vital al proporcionar descuentos a los usuarios y mejorar la experiencia de compra. Se apoya en el `DiscountCodeController` para su gestión y utiliza `DiscountCodeRepository` para la transacción y flujo de datos en el sistema. Los principales atributos de `DiscountCode` son: - **code (String):** El identificador único y alfanumérico del código de descuento. - **value (double):** Representa el valor de descuento que el código aporta, ya sea como un monto fijo o un porcentaje. Este diseño permite una fácil integración con los sistemas de carrito y pago, garantizando que los descuentos se apliquen correctamente y se gestionen de manera eficiente. ### Payment `Payment` es la entidad responsable de representar la transacción de pago realizada por un usuario en la aplicación. Para su gestión y funcionamiento, cuenta con un `PaymentController` dedicado. No requiere de un `Repository` específico, ya que la información se guarda conjuntamente con la entidad `Order`. Los atributos principales de `Payment` incluyen: - **paymentID (int):** Identificador único del pago. - **amount (double):** Monto total a pagar. - **paymentMethod (PaymentMethod):** Relacionado con el Enum `PaymentMethod`, que contiene todos los métodos de pago posibles. - **paymentDateTime (LocalDateTime):** Fecha y hora exacta del pago. - **lastFourDigits (String):** Muestra únicamente los últimos cuatro dígitos de la tarjeta utilizada, garantizando la privacidad y seguridad del usuario. #### Notas adicionales sobre `Payment` Por el momento, se trabaja exclusivamente con tarjetas de crédito como método de pago y de forma ficticia, dados los recursos disponibles para integrar un sistema de transacciones bancarias auténtico. Actualmente, no se realiza una verificación real de la tarjeta de crédito; simplemente se comprueba que el número de tarjeta tenga 16 dígitos, que el CVV contenga 3 dígitos y que la fecha de vencimiento esté correctamente formatada. Para una validación genuina, sería esencial modificar el `PaymentController` para integrarse con una API bancaria o un servicio similar. Sin embargo, esta implementación solo se llevará a cabo si se dispone de los recursos y herramientas necesarios. ### Order La entidad `Order` simboliza una orden realizada por un usuario. Para el manejo de datos y flujo de información, se apoya en el `OrderController` y el `OrderRepository`. Es crucial mencionar que esta entidad agrupa otras entidades fundamentales como `Cart` y `Payment`. Sus atributos centrales son: - **orderID (int)**: Identificador único para la orden. - **cart (Cart)**: Representa el carrito asociado con la orden. - **orderDateTime (LocalDateTime)**: Fecha y hora en que se realizó la orden. - **payment (Payment)**: Información de pago asociada a la orden. #### Notas adicionales sobre `Order`: 1. Actualmente, el sistema cuenta solo con una orden de prueba que puede ser revisada por el usuario administrador. Esta implementación sirve para simular una interacción real y será mejorada con la introducción de una base de datos. 2. La entidad `Order` no posee un atributo `userID` que la relacione directamente con un usuario. Esta característica está en planes de implementación, una vez que se tenga la instancia de usuario en el sistema, permitiendo asociar y buscar órdenes por usuario específico. ### Flujos Principales de Entidades A continuación, se presenta el principal flujo de datos entre las entidades de la aplicación: - **Product**: View - ProductController - ProductRepository - **Order**: View - OrderController - OrderRepository - **DiscountCode**: View - DiscountCodeController - DiscountCodeRepository ### Excepciones en la Estructura Existen ciertas excepciones en este flujo: - **CheckoutController**: Actúa como un intermediario para la creación de una orden (Order) y el proceso de pago (Payment). Por ello, no interactúa directamente con una base de datos. - **CartController**: Se genera en la instancia actual de la aplicación y se almacena en el detalle de la orden. Debido a esto, no necesita interacción con una base de datos. - **PaymentController**: Se crea y se almacena junto con la orden, y se necesita para la selección del método de pago, por lo que no requiere interacción con una base de datos. ### Reflexión sobre el Diseño Las excepciones mencionadas se deben principalmente a una intención de mantener un diseño sistemáticamente simple en la interacción con las entidades dentro de la base de datos. Tanto el pago (Payment) como el carrito (Cart) se almacenan directamente en la orden (Order). Aunque esto puede no ser ideal en situaciones donde la escalabilidad sea una prioridad, esta estructura se considera adecuada para el diseño actual del sistema. Sin embargo, en futuras versiones de la aplicación, sería recomendable reconsiderar esta estructura, atomizando lo más posible cada entidad dentro de las tablas en el sistema de almacenamiento de datos, y aplicando ciertas formas normales a éstas últimas, especialmente si la escalabilidad se convierte en una preocupación central. --- ## 3. Funcionalidades Desarrolladas Dentro de esta sección, se describen en detalle las funcionalidades implementadas en el proyecto, proporcionando una comprensión clara y concisa de las capacidades y características desarrolladas. --- ### 3.1 Funcionalidad de Navegación: Clase NavigationHandler Dentro del paquete `navigation`, se encuentra una clase crucial denominada `NavigationHandler`. Esta clase ha sido diseñada para gestionar de forma eficiente la navegación entre los menús del proyecto, adoptando un comportamiento similar al de una estructura de datos tipo stack (pila). ### Navegación Tipo Stack La navegación tipo stack permite a los usuarios desplazarse cómodamente entre los menús, teniendo la capacidad de avanzar hacia nuevos menús y regresar a menús anteriores. Esta estructura garantiza que se mantenga un orden lógico y coherente en la navegación del usuario. ### Métodos Principales 1. **navigateTo(Menu menu)**: - Este método permite avanzar hacia un nuevo menú. - Se espera que el parámetro `menu` sea una instancia de una clase que herede de la clase abstracta `Menu`. - Al invocar este método, la instancia del menú proporcionada se coloca (o apila) en la estructura de stack, quedando en la cima. 2. **goBack()**: - Facilita la navegación hacia el menú anterior. - Al invocar este método, se retira (o desapila) el menú actual de la cima del stack, permitiendo que el usuario regrese al menú que se encontraba inmediatamente antes en la secuencia de navegación. 3. **pushReplacement(Menu menu)**: - Esta función, además de colocar un nuevo menú en la cima del stack, elimina todos los menús que estaban previamente en la pila, dejando solamente el nuevo menú proporcionado. - Es útil para situaciones donde se desea iniciar una nueva secuencia de navegación sin la necesidad de mantener el historial anterior. La implementación de estos métodos y la estructura tipo stack en `NavigationHandler` aseguran una navegación fluida, intuitiva y organizada para los usuarios, permitiendo una experiencia de usuario optimizada y coherente. --- ### 3.2 Funcionalidades de Usuarios : Menús Las funcionalidades específicas para cada tipo de usuario se reflejan en las vistas de la aplicación, alojadas en el paquete `views/menus`. La gestión y navegación de estas vistas se realiza a través de una clase principal: `MenuHandler`. #### MenuHandler `MenuHandler` es la clase encargada de determinar y presentar el menú adecuado en función del tipo de usuario que ingrese, una vez que se cuente con una instancia concreta del mismo. El método principal de esta clase es `startApp()`, el cual define la vista inicial que se mostrará al usuario. Es importante señalar que el método `startApp()` tiene una conexión directa con la clase principal del módulo, denominada `App`. A través del método `run()` en `App`, se realiza una llamada a `MenuHandler`, activando la interfaz de usuario correspondiente y dando inicio a la interacción. ### 3.2.1 Usuario Común **Descripción general**: El usuario común posee diversas acciones y capacidades dentro de la aplicación, permitiéndole navegar y gestionar sus productos de interés a través de diversos menús. #### Menú Principal: Clase `MainMenu` Las acciones disponibles en el menú principal para el usuario común son: - **Ver todos los productos**: Permite al usuario visualizar todos los productos disponibles en la aplicación. - **Buscar productos**: Facilita la búsqueda específica de productos según las necesidades o gustos del usuario. - **Agregar productos al carrito**: Brinda la opción de añadir productos seleccionados al carrito de compras del usuario. - **Mostrar el carrito**: Navega al menú específico del carrito, representado por la clase `CartMenu`. #### Menú del Carrito: Clase `CartMenu` Una vez dentro del menú del carrito, el usuario cuenta con las siguientes opciones: - **Mostrar productos en el carrito**: Visualizar todos los productos que ha agregado previamente al carrito. - **Modificar cantidad de un producto**: Permite ajustar la cantidad deseada de un producto específico dentro del carrito. - **Eliminar un producto del carrito**: Facilita la eliminación de productos que el usuario decida no adquirir. - **Ir a pagar**: Navega hacia el menú de finalización de compra, representado por la clase `CheckoutMenu`. #### Menú de Finalización de Compra: Clase `CheckoutMenu` En el menú destinado a finalizar la compra, el usuario tiene a su disposición las siguientes acciones: - **Revisar el carrito**: Posibilita una revisión final de los productos seleccionados antes de concretar la compra. - **Ingresar información y método de pago**: Espacio donde el usuario proporciona los detalles para procesar el pago. - **Aplicar un código de descuento**: En caso de contar con uno, permite la inserción de un código promocional. - **Finalizar compra y generar orden**: Una vez satisfecho con su selección y datos proporcionados, el usuario puede finalizar su compra, generando así una orden en el sistema. ### 🎥 Vídeo Demostrativo En el siguiente enlace, se pueden ver las principales funcionalidades asociadas al usuario común: [🔗 Ver Vídeo en Google Drive](https://drive.google.com/file/d/1qbysXkMQOmvRdMljdng_Lfph8VzR3hes/view?usp=sharing) --- ### 3.2.2 Usuario Administrador **Descripción general**: El usuario administrador dispone de capacidades ampliadas dentro de la aplicación, permitiendo gestionar varios aspectos clave con un enfoque administrativo. #### Menú Principal Administrativo: Clase `AdminMainMenu` Las acciones principales disponibles en el menú del administrador son: - **Gestionar Catálogo de Productos**: Navega a un submenú específico para la gestión de productos, representado por la clase `ProductManagementMenu`. - **Gestionar Transacciones**: Dirige al usuario a un submenú dedicado a la gestión de transacciones, representado por la clase `OrderManagementMenu`. - **Gestionar Ofertas (Códigos de descuento)**: Navega hacia un submenú destinado a la administración de códigos promocionales, representado por la clase `DiscountManagementMenu`. #### Submenú de Gestión de Productos: Clase `ProductManagementMenu` Dentro de este submenú, el administrador tiene las siguientes opciones: - **Mostrar todos los productos**: Visualización completa del catálogo de productos disponibles. - **Buscar Productos**: Permite la búsqueda de productos ya sea por su ID o por coincidencia en el nombre. - **Eliminar Producto**: Facilita la eliminación de un producto del catálogo. #### Submenú de Gestión de Transacciones: Clase `OrderManagementMenu` Las capacidades en este submenú incluyen: - **Listar todas las órdenes**: Presenta un resumen de todas las transacciones realizadas en la aplicación. - **Buscar Orden por ID**: Posibilita la búsqueda específica de una transacción mediante su identificador. **Nota**: En base a las conversaciones previas con el módulo de Cuentas de Usuario, se tiene la intención de agregar una funcionalidad adicional que permitiría buscar una orden a través del ID de usuario asociado. Sin embargo, debido a que actualmente no se puede acceder a una instancia del usuario, gestionado por dicho módulo, esta funcionalidad está en espera de implementación. #### Submenú de Gestión de Códigos de Descuento: Clase `DiscountManagementMenu` En esta sección, el administrador puede: - **Crear un nuevo código de descuento**: Permite introducir nuevos códigos promocionales al sistema. - **Eliminar un código de descuento**: Facilita la remoción de códigos que ya no están en uso o que se desean descartar. - **Buscar un código de descuento**: Búsqueda específica de códigos promocionales. - **Listar todos los códigos de descuento**: Visualización completa de todos los códigos disponibles para promociones. ### 🎥 Vídeo Demostrativo En el siguiente enlace, se pueden ver las principales funcionalidades asociadas al usuario administrador: [🔗 Ver Vídeo en Google Drive](https://drive.google.com/file/d/11Lipq7zS4vTadsUt1i9hN_UhfqLBK5lO/view?usp=sharing) --- ### 3.2.3 Usuario Dev El usuario `dev` desempeña un rol vital dentro de la aplicación, teniendo una serie de acciones especiales a su disposición, centradas en la gestión de juegos. Las funcionalidades son las siguientes: #### Gestión de Juegos - **Registrar/Crear un nuevo juego**: Permite a los desarrolladores añadir nuevos títulos a la plataforma. - **Eliminar juego**: Esta función requiere especificar un ID para identificar y eliminar el juego correspondiente. - **Actualizar detalles del juego**: Mediante un ID, el desarrollador puede modificar detalles específicos del juego. - **Nota**: Esta funcionalidad está parcialmente completada. Se espera concluir su implementación en la próxima entrega, permitiendo que el usuario determine qué aspectos específicos del juego desea modificar. - **Listar sus juegos**: Ofrece un resumen de todos los juegos asociados al desarrollador. - **Nota**: Dado que se trabaja con datos simulados y aún no hay una instancia del usuario en el sistema, esta funcionalidad será perfeccionada en la próxima entrega. - **Buscar sus juegos**: La búsqueda se puede realizar por coincidencia de nombre o mediante un ID. - **Nota**: Esta función también está pendiente de ajustes debido a la falta de una instancia del usuario. - **Ver número de venta de sus juegos**: Una herramienta que permite visualizar el éxito comercial de sus títulos. - **Nota**: Al igual que otras funciones, esta necesita mejoras por las mismas razones previamente mencionadas. #### Reflexión sobre el Desarrollo del Usuario Dev A lo largo de la implementación, ha quedado claro que el perfil de usuario `dev` necesita un enfoque y trabajo intensivo para su correcta implementación. Esta situación tiene su origen en la decisión tardía del módulo de Cuentas de Usuario sobre cómo manejar la instancia del usuario. No obstante, en recientes reuniones, se acordó la incorporación del usuario `dev` dentro de este módulo. Por ello, se espera que para la próxima entrega, este perfil esté completamente desarrollado y operativo. ### 🎥 Vídeo Demostrativo En el siguiente enlace, se pueden ver las principales funcionalidades asociadas al usuario dev: [🔗 Ver Vídeo en Google Drive](https://drive.google.com/file/d/10TQ7uUfKXNinLQJL6jE8-yjizPz9Kira/view?usp=sharing) --- ## 3. Utilidades En el marco del desarrollo de la aplicación, se ha establecido un paquete denominado `utils` que organiza y alberga las diferentes utilidades o "handlers" que facilitan y optimizan la operatividad del sistema. A continuación, se detallan estas utilidades: ### DisplayHandler `DisplayHandler` actúa como el principal administrador de la presentación de las vistas en la consola. A través de sus métodos, esta herramienta ofrece soluciones para mostrar y formatear la información de manera adecuada, garantizando una experiencia amigable para el usuario. Es ampliamente utilizada por clases que derivan tanto de `Menu` como de `Controller`, para presentar y actualizar la información visualizada por el usuario. ### InputHandler `InputHandler` está destinada a administrar y validar las entradas o "inputs" realizadas por el usuario. Gracias a esta utilidad y sus respectivos métodos, es posible verificar que las entradas del usuario sean las adecuadas; por ejemplo, garantizar que un input esperado como un entero (`int`) no sea ingresado como una cadena de texto (`String`). Al igual que `DisplayHandler`, esta herramienta es esencial para clases que heredan de `Menu` y de `Controller`. ### Messages El módulo `Messages` tiene el propósito de contener mensajes estáticos que se despliegan al usuario. Al conservar estos mensajes como constantes, se facilita la adaptabilidad del sistema; por ejemplo, si en el futuro se desea implementar soporte multilenguaje, simplemente sería necesario traducir los textos almacenados en esta utilidad, favoreciendo la escalabilidad y accesibilidad de la aplicación. ### ANSIColors Finalmente, `ANSIColors` se encarga de enriquecer la experiencia visual del usuario al almacenar y administrar los colores empleados en las vistas gestionadas por `DisplayHandler`. Estos colores, almacenados en formato ANSI, garantizan compatibilidad con la mayoría de las consolas o terminales en uso, proporcionando un ambiente visual atractivo y amigable para el usuario. --- ## 4. Análisis de la Complejidad Ciclomática La complejidad ciclomática es una métrica de software que mide la cantidad de caminos independientes a través del código fuente de un programa. Esencialmente, indica cuántos flujos diferentes o caminos lógicos puede tomar un programa durante su ejecución. Esta métrica es útil para determinar la complejidad de un programa y, por lo tanto, puede ayudar a identificar áreas que podrían beneficiarse de pruebas adicionales o refactoring. Un valor más alto suele indicar una mayor complejidad y potencialmente un mayor riesgo de defectos. ### Complejidad Ciclomática Total En el contexto del proyecto, se observa una complejidad ciclomática total significativamente alta, alcanzando un valor de **305**. ![Imagen de la complejidad ciclomática total](https://hackmd.io/_uploads/rJZksLtfp.png) Esta magnitud puede ser inicialmente alarmante, pero su interpretación adquiere sentido al considerar la estructura y funcionamiento del sistema. Para proporcionar un panorama más claro: 1. **Cantidad de métodos y clases**: La aplicación cuenta con 170 métodos distribuidos en 35 clases. ![Imagen de cantidad de métodos y clases](https://hackmd.io/_uploads/H1HEiLFza.png) La complejidad ciclomática es un valor acumulativo, por lo que un sistema con un número elevado de métodos y clases tenderá a tener un valor de complejidad más alto. 2. **Estructuras switch-case**: Las clases que heredan de `Menu` emplean extensivamente estructuras `switch-case` para gestionar las opciones ingresadas por el usuario. Debido a que existen tres tipos de usuarios (Admin, Dev y el usuario común), es imperativo tener múltiples menús que contemplan diferentes interacciones. Además, los menús anidados y las actualizaciones de vistas a través de `Controller` incrementan la complejidad. 3. **Métodos de gestión de menús**: Cada clase que hereda de `Menu` implementa métodos como `runMenuLoop()`, que encapsula la estructura `switch-case` dentro de un bucle, permitiendo una correcta funcionalidad del menú. Esto conlleva a un incremento exponencial en los caminos dentro de un menú, reflejándose directamente en la complejidad ciclomática. **Posible solución**: Para mitigar este crecimiento en la complejidad, sería recomendable considerar el uso de librerías de interfaces gráficas como JavaFX. Esta aproximación reduciría la necesidad de estructuras `switch-case` al gestionar menús, y por consiguiente, reduciría la complejidad asociada. ### Complejidad Ciclomática por Método La complejidad ciclomática por método se calcula dividiendo la complejidad ciclomática total entre el número de métodos. En este caso, el valor resultante es **1.79 por método**. Este valor representa el promedio de caminos distintos que un método puede tomar durante su ejecución. Aunque el valor total de la complejidad es alto, un valor de 1.79 por método sugiere que, en promedio, los métodos del sistema no son excesivamente complejos por sí mismos. **Evaluación de Riesgo**: A pesar de la complejidad ciclomática total elevada, el valor por método es bastante razonable. Esto sugiere que el sistema, a pesar de su complejidad global, está compuesto por métodos individuales que son manejables y, en su mayoría, directos. Al compararlo con la complejidad total, es evidente que la principal contribución a la complejidad se debe a la estructura general y la gestión de menús, y no a la complejidad intrínseca de los métodos individuales. --- ## 5. Análisis de Acoplamiento (CBO) ### 5.1 Identificación de clases y organización según el patrón MVC y la capa de repositorios #### Modelo (Model) - `Cart` - `CartItem` - `DiscountCode` - `Order` - `Payment` #### Vista (View/Menu) - `AdminMainMenu` - `DiscountManagementMenu` - `OrderManagementMenu` - `ProductManagementMenu` - `DevMainMenu` - `CartMenu` - `CheckoutMenu` - `MainMenu` - `Menu` (Clase Abstracta) - `MenuHandler` #### Controlador (Controller) - `CartController` - `CheckoutController` - `Controller` (Clase abstracta) - `DiscountCodeController` - `OrderController` - `PaymentController` - `ProductController` #### Repositorios - `DiscountCodeRepository` - `OrderRepository` - `ProductRepository` - `Repository` (Interface) #### Utils - `ANSIColors` - `DisplayHandler` - `NavigationHandler` - `InputHandler` - `Messages` #### Otros - `App` - `Main` ### 5.2 Diagrama de Dominio ![](https://hackmd.io/_uploads/ry9TLt2za.png) ### 5.3 Análisis de CBO (Coupling Between Object classes) | Clase | CBO | |------------------------|-----| | `App` | 1 | | `MenuHandler` | 5 | #### Models | Clase | CBO | |----------------|-----| | `Cart` | 3 | | `CartItem` | 1 | | `Payment` | 2 | | `Order` | 4 | | `DiscountCode` | 2 | | `Product` | 2 | #### Views/Menus | Clase | CBO | |-------------------|-----| | `MainMenu` | 7 | | `AdminMainMenu` | 7 | | `DevMainMenu` | 7 | #### Controllers | Clase | CBO | |-------------------------|-----| | `PaymentController` | 7 | | `OrderController` | 8 | | `CheckoutController` | 8 | | `DiscountCodeController`| 7 | | `ProductController` | 7 | | `CartController` | 7 | > **Nota:** Hay ciertos controladores que no se conectan a un repositorio, específicamente `CartController`, `PaymentController` y `CheckoutController`, por lo que tienen una relación menos. #### Repositories | Clase | CBO | |-------------------------|-----| | `ProductRepository` | 1 | | `DiscountCodeRepository`| 1 | | `OrderRepository` | 1 | #### Utils | Clase | CBO | |------------------|-----| | `NavigationHandler` | 2 | | `InputHandler` | 3 | | `DisplayHandler` | 3 | | `ANSIColors` | 2 | | `Messages` | 2 | --- ### Plan de Mejora A partir del análisis de CBO, se identifica que los controladores presentan un alto grado de acoplamiento. Sin embargo, algunos de ellos, como `CartController`, `PaymentController` y `CheckoutController`, tienen un acoplamiento ligeramente reducido debido a la falta de conexión con los repositorios. Las clases dentro de la sección de "Views/Menus" también muestran un elevado CBO, sugiriendo una intensa interacción con otras partes del sistema. Por otro lado, las clases utilitarias y los modelos presentan un CBO más equilibrado. Estos hallazgos generales nos llevan a proponer ciertas mejoras en la estructura del sistema. En base a lo anterior, se podría considerar: 1. **Inyección de Dependencias**: Implementar la inyección de dependencias puede ser útil, especialmente para clases utilitarias. Esta práctica no solo facilitaría las pruebas sino que reduciría el acoplamiento. Actualmente, se hacen llamadas estáticas a clases utilitarias como `Messages` y `ANSIColors`, lo que hace que la dependencia esté firmemente codificada. La inyección de dependencias ayudaría a separar las dependencias de su implementación. 2. **Uso de Interfaces Gráficas**: Al utilizar librerías de interfaces gráficas como JavaFX, es posible reducir el número de clases relacionadas con las vistas, lo que a su vez reduce el CBO para los controladores. 3. **Capa de Abstracción Adicional**: Pensando en la escalabilidad y los principios SOLID, agregar una capa de servicios o `services` sería beneficioso. Esto permitiría que los controladores manejen principalmente la interacción con la interfaz del usuario y deleguen la lógica a los servicios; los controladores pasarían a tener una única responsabilidad: mediar entre la vista y los servicios. --- ## 6. Análisis de Cohesión por Clase: `ProductRepository` ### LCOM (Lack of Cohesion in Methods) El método **LCOM** (Lack of Cohesion in Methods) es una métrica que evalúa la cohesión entre los métodos de una clase. Aunque la cohesión puede ser interpretada subjetivamente, el LCOM proporciona una forma cuantitativa de medirlo. La clase `ProductRepository` contiene los siguientes métodos que operan sobre la única variable de instancia presente, `products`: - `loadProducts()` - `findAll()` - `findByID(int id)` - `findByName(String name)` - `deleteByID(int id)` - `save(Product entity)` - `exists(int id)` - `existsByName(String name)` ### Cálculo del LCOM: 1. Se crea un conjunto para cada método que contiene las variables de instancia que utiliza. 2. Se cuentan cuántos conjuntos no tienen intersección entre sí. 3. Se cuentan cuántos conjuntos sí tienen intersección entre sí. 4. **LCOM** = Número de conjuntos sin intersección - Número de conjuntos con intersección. Si todos los conjuntos tienen al menos una intersección con otro conjunto, entonces **LCOM** = 0, indicando una alta cohesión. Si **LCOM** > 0, la cohesión es baja. Para `ProductRepository`, todos los métodos acceden a la variable de instancia `products`. Por lo tanto, todos los conjuntos tendrán intersección con otros conjuntos. Esto resulta en un **LCOM = 0**, indicando alta cohesión. ### Tipo de Cohesión: La clase exhibe cohesión funcional, ya que todos los métodos están relacionados con una función específica: administrar productos. Cada método tiene la tarea de acceder, consultar o modificar una lista de productos. ### Mejoras: - La gestión de la carga de productos desde un archivo JSON podría delegarse en una clase dedicada o en un método de una clase de utilidad para reducir la responsabilidad de `ProductRepository` y aumentar la cohesión funcional. - Aunque la clase muestra cohesión, tiene una variedad de responsabilidades, incluida la lectura del archivo JSON. Siguiendo el principio de responsabilidad única, sería recomendable tener una clase separada para cargar productos desde archivos o fuentes de datos externas. - El manejo de errores, como el hecho de imprimir el error directamente en `loadProducts()`, podría mejorarse. En lugar de simplemente imprimir el error, sería recomendable lanzar una excepción personalizada y manejarla en una capa superior.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully