Saltar a contenido

Semana 12 - Evaluación Segundo Momento

La evaluación de conocimiento se realizará a través de la plataforma Quizizz que aborda los temas vistos durante las primeras 5 semanas.

  • Plataforma: Enlace Quizizz
  • Acceso: Se proporcionará el enlace y código de la prueba al inicio de la evaluación

Actividad: Implementación de una Tienda Virtual en Java

Contexto

En esta actividad, implementarás una Tienda Virtual en Java que permita gestionar productos, usuarios, carritos de compra y procesar pagos. La aplicación debe utilizar los principales conceptos de Programación Orientada a Objetos (POO), incluyendo encapsulamiento, herencia, polimorfismo, abstracción, interfaces y manejo de excepciones. La tienda virtual será una aplicación práctica que simule un sistema de comercio electrónico, y se proporcionará un ejemplo similar (un Sistema de Biblioteca) como referencia.

Objetivos

  1. Aplicar los conceptos de POO en el diseño e implementación de una aplicación funcional.
  2. Completar una plantilla de código con secciones marcadas como TODO, siguiendo las instrucciones específicas.
  3. Asegurar que la aplicación gestione correctamente productos, carritos y pagos, manteniendo los principios de POO.
  4. Comparar la implementación con un ejemplo funcional (Sistema de Biblioteca) para entender la estructura y lógica.

Instrucciones

  1. Código a completar: A continuación, se proporciona una plantilla de código (TiendaVirtualActividad.java) con secciones marcadas como TODO. Cada TODO incluye instrucciones detalladas en comentarios sobre qué implementar. Debes:
    • Completar todas las secciones marcadas con TODO.
    • Seguir las instrucciones específicas en cada comentario.
    • Asegurarte de que el código respete los principios de POO (por ejemplo, encapsulamiento en los atributos, polimorfismo en las clases que heredan, etc.).
  2. Ejemplo de referencia: Se incluye un código completo (SistemaBiblioteca.java) que implementa un sistema similar (una biblioteca que gestiona libros, usuarios y préstamos). Usa este ejemplo para:
    • Entender cómo se implementan los conceptos de POO en un contexto similar.
    • Comparar la estructura de clases, interfaces y métodos para guiarte en la implementación de la tienda virtual.
  3. Pruebas: El método main de la plantilla incluye un caso de uso. Una vez completes los TODO, ejecuta el programa para verificar que:
    • Se muestre el inventario correctamente.
    • Se puedan agregar productos al carrito.
    • Se procesen pagos correctamente.
    • Se manejen excepciones (por ejemplo, carrito vacío o producto sin stock).
  4. Entrega: Entrega el código completo y funcional, con todos los TODO resueltos. Asegúrate de que el programa compile y ejecute sin errores.

Código a Completar (TiendaVirtualActividad.java)

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

// Actividad: Implementar una tienda virtual usando conceptos de POO
// Instrucciones generales:
// - Completar todos los TODO en el código
// - Cada TODO tiene instrucciones específicas
// - Mantener los principios de POO: encapsulamiento, herencia, polimorfismo, abstracción
// - Probar la funcionalidad en el método main

// TODO 1: Crear una excepción personalizada llamada TiendaException que herede de Exception
// Instrucciones: 
// - Crear constructor que reciba un mensaje
// - Usar super() para pasar el mensaje al constructor de Exception
class TiendaException /* TODO */ {
    // TODO: Implementar constructor
}

// TODO 2: Crear una interfaz MetodoPago con dos métodos abstractos
// Instrucciones:
// - Definir método procesarPago que reciba un double y retorne boolean
// - Definir método obtenerDetalles que retorne String
interface MetodoPago {
    // TODO: Declarar métodos
}

// TODO 3: Crear clase abstracta Producto con atributos y métodos
// Instrucciones:
// - Crear atributos privados: id (String), nombre (String), precio (double), stock (int)
// - Crear constructor que inicialice nombre, precio, stock (id usar UUID.randomUUID().toString())
// - Implementar getters para todos los atributos
// - Implementar setter solo para stock
// - Declarar método abstracto getDetalles()
abstract class Producto {
    // TODO: Declarar atributos privados
    // TODO: Implementar constructor
    // TODO: Implementar getters y setter
    // TODO: Declarar método abstracto getDetalles
}

// TODO 4: Crear clase ProductoElectronico que herede de Producto
// Instrucciones:
// - Agregar atributo privado garantiaMeses (int)
// - Implementar constructor que use super() para los atributos de Producto
// - Implementar getDetalles() retornando String con nombre, precio, stock y garantía
class ProductoElectronico extends Producto {
    // TODO: Declarar atributo garantiaMeses
    // TODO: Implementar constructor
    // TODO: Implementar getDetalles
}

// TODO 5: Crear clase ProductoRopa que herede de Producto
// Instrucciones:
// - Agregar atributo privado talla (String)
// - Implementar constructor que use super() para los atributos de Producto
// - Implementar getDetalles() retornando String con nombre, precio, stock y talla
class ProductoRopa extends Producto {
    // TODO: Declarar atributo talla
    // TODO: Implementar constructor
    // TODO: Implementar getDetalles
}

// TODO 6: Implementar clase PagoTarjeta que implemente MetodoPago
// Instrucciones:
// - Agregar atributo privado numeroTarjeta (String)
// - Implementar constructor
// - Implementar procesarPago imprimiendo mensaje y retornando true
// - Implementar obtenerDetalles retornando últimos 4 dígitos de la tarjeta
class PagoTarjeta implements MetodoPago {
    // TODO: Declarar atributo numeroTarjeta
    // TODO: Implementar constructor
    // TODO: Implementar procesarPago
    // TODO: Implementar obtenerDetalles
}

// TODO 7: Implementar clase CarritoCompra
// Instrucciones:
// - Agregar atributo privado productos (List<Producto>)
// - Implementar constructor que inicialice la lista
// - Implementar agregarProducto que valide stock y lance TiendaException si no hay stock
// - Implementar calcularTotal que sume precios de productos
// - Implementar getProductos que retorne copia de la lista
class CarritoCompra {
    // TODO: Declarar atributo productos
    // TODO: Implementar constructor
    // TODO: Implementar agregarProducto
    // TODO: Implementar calcularTotal
    // TODO: Implementar getProductos
}

// TODO 8: Implementar clase Usuario
// Instrucciones:
// - Agregar atributos privados: nombre (String), email (String), carrito (CarritoCompra)
// - Implementar constructor que inicialice todos los atributos
// - Implementar getters para todos los atributos
class Usuario {
    // TODO: Declarar atributos
    // TODO: Implementar constructor
    // TODO: Implementar getters
}

// TODO 9: Implementar clase TiendaVirtual
// Instrucciones:
// - Agregar atributos privados: inventario (List<Producto>), usuarios (List<Usuario>)
// - Implementar constructor que inicialice las listas
// - Implementar agregarProducto para añadir al inventario
// - Implementar registrarUsuario para añadir usuario
// - Implementar realizarCompra que valide carrito no vacío y procese pago
// - Implementar mostrarInventario que imprima detalles de productos
class TiendaVirtual {
    // TODO: Declarar atributos
    // TODO: Implementar constructor
    // TODO: Implementar agregarProducto
    // TODO: Implementar registrarUsuario
    // TODO: Implementar realizarCompra
    // TODO: Implementar mostrarInventario
}

// Clase main con ejemplo de uso
public class Main {
    public static void main(String[] args) {
        try {
            // Crear tienda
            TiendaVirtual tienda = new TiendaVirtual();

            // Agregar productos
            Producto laptop = new ProductoElectronico("Laptop Gaming", 1200.0, 5, 24);
            Producto camiseta = new ProductoRopa("Camiseta Algodón", 25.0, 10, "M");
            tienda.agregarProducto(laptop);
            tienda.agregarProducto(camiseta);

            // Crear usuario
            Usuario cliente = new Usuario("Juan Pérez", "juan@email.com");
            tienda.registrarUsuario(cliente);

            // Mostrar inventario
            tienda.mostrarInventario();

            // Agregar productos al carrito
            cliente.getCarrito().agregarProducto(laptop);
            cliente.getCarrito().agregarProducto(camiseta);

            // Realizar compra
            MetodoPago tarjeta = new PagoTarjeta("1234567890123456");
            tienda.realizarCompra(cliente, tarjeta);

            // Mostrar inventario actualizado
            tienda.mostrarInventario();

        } catch (TiendaException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}

Código de Ejemplo (SistemaBiblioteca.java)

Este código implementa un sistema de biblioteca que gestiona libros, revistas, usuarios y préstamos, usando los mismos conceptos de POO. Utilízalo como referencia para entender cómo implementar las clases, métodos y relaciones en la tienda virtual.

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

// Excepción personalizada para la biblioteca
class BibliotecaException extends Exception {
    public BibliotecaException(String mensaje) {
        super(mensaje);
    }
}

// Interfaz para métodos de notificación
interface MetodoNotificacion {
    boolean enviarNotificacion(String mensaje);
    String obtenerDetalles();
}

// Clase abstracta para ítems de la biblioteca
abstract class ItemBiblioteca {
    private String id;
    private String titulo;
    private String autor;
    private int copiasDisponibles;

    public ItemBiblioteca(String titulo, String autor, int copiasDisponibles) {
        this.id = UUID.randomUUID().toString();
        this.titulo = titulo;
        this.autor = autor;
        this.copiasDisponibles = copiasDisponibles;
    }

    // Encapsulamiento
    public String getId() { return id; }
    public String getTitulo() { return titulo; }
    public String getAutor() { return autor; }
    public int getCopiasDisponibles() { return copiasDisponibles; }
    public void setCopiasDisponibles(int copias) { this.copiasDisponibles = copias; }

    // Método abstracto
    public abstract String getDetalles();
}

// Clase concreta que hereda de ItemBiblioteca
class Libro extends ItemBiblioteca {
    private int numeroPaginas;

    public Libro(String titulo, String autor, int copiasDisponibles, int numeroPaginas) {
        super(titulo, autor, copiasDisponibles);
        this.numeroPaginas = numeroPaginas;
    }

    @Override
    public String getDetalles() {
        return String.format("Libro: %s, Autor: %s, Copias: %d, Páginas: %d",
                getTitulo(), getAutor(), getCopiasDisponibles(), numeroPaginas);
    }
}

// Clase concreta que hereda de ItemBiblioteca
class Revista extends ItemBiblioteca {
    private String edicion;

    public Revista(String titulo, String autor, int copiasDisponibles, String edicion) {
        super(titulo, autor, copiasDisponibles);
        this.edicion = edicion;
    }

    @Override
    public String getDetalles() {
        return String.format("Revista: %s, Autor: %s, Copias: %d, Edición: %s",
                getTitulo(), getAutor(), getCopiasDisponibles(), edicion);
    }
}

// Implementación de MetodoNotificacion
class NotificacionEmail implements MetodoNotificacion {
    private String emailDestino;

    public NotificacionEmail(String emailDestino) {
        this.emailDestino = emailDestino;
    }

    @Override
    public boolean enviarNotificacion(String mensaje) {
        System.out.println("Enviando email a " + emailDestino + ": " + mensaje);
        return true;
    }

    @Override
    public String obtenerDetalles() {
        return "Email: " + emailDestino;
    }
}

// Clase para el registro de préstamos
class RegistroPrestamo {
    private List<ItemBiblioteca> itemsPrestados;

    public RegistroPrestamo() {
        this.itemsPrestados = new ArrayList<>();
    }

    public void agregarItem(ItemBiblioteca item) throws BibliotecaException {
        if (item.getCopiasDisponibles() <= 0) {
            throw new BibliotecaException("No hay copias disponibles de: " + item.getTitulo());
        }
        itemsPrestados.add(item);
        item.setCopiasDisponibles(item.getCopiasDisponibles() - 1);
    }

    public int contarItems() {
        return itemsPrestados.size();
    }

    public List<ItemBiblioteca> getItemsPrestados() {
        return new ArrayList<>(itemsPrestados);
    }
}

// Clase para el usuario
class MiembroBiblioteca {
    private String nombre;
    private String idMiembro;
    private RegistroPrestamo registro;

    public MiembroBiblioteca(String nombre, String idMiembro) {
        this.nombre = nombre;
        this.idMiembro = idMiembro;
        this.registro = new RegistroPrestamo();
    }

    public String getNombre() { return nombre; }
    public String getIdMiembro() { return idMiembro; }
    public RegistroPrestamo getRegistro() { return registro; }
}

// Clase principal de la biblioteca
class SistemaBiblioteca {
    private List<ItemBiblioteca> catalogo;
    private List<MiembroBiblioteca> miembros;

    public SistemaBiblioteca() {
        this.catalogo = new ArrayList<>();
        this.miembros = new ArrayList<>();
    }

    public void agregarItem(ItemBiblioteca item) {
        catalogo.add(item);
    }

    public void registrarMiembro(MiembroBiblioteca miembro) {
        miembros.add(miembro);
    }

    public boolean procesarPrestamo(MiembroBiblioteca miembro, MetodoNotificacion notificacion) throws BibliotecaException {
        RegistroPrestamo registro = miembro.getRegistro();
        if (registro.contarItems() == 0) {
            throw new BibliotecaException("El registro de préstamo está vacío");
        }

        String mensaje = "Préstamo procesado para " + miembro.getNombre() + ". Ítems: " + registro.contarItems();
        if (notificacion.enviarNotificacion(mensaje)) {
            System.out.println("Préstamo exitoso. Notificación enviada a: " + notificacion.obtenerDetalles());
            return true;
        }
        return false;
    }

    public void mostrarCatalogo() {
        System.out.println("\nCatálogo disponible:");
        for (ItemBiblioteca item : catalogo) {
            System.out.println(item.getDetalles());
        }
    }
}

// Clase main para demostrar el uso
public class Main {
    public static void main(String[] args) {
        try {
            // Crear biblioteca
            SistemaBiblioteca biblioteca = new SistemaBiblioteca();

            // Agregar ítems
            ItemBiblioteca libro = new Libro("Cien Años de Soledad", "Gabriel García Márquez", 3, 450);
            ItemBiblioteca revista = new Revista("National Geographic", "Varios", 5, "Enero 2025");
            biblioteca.agregarItem(libro);
            biblioteca.agregarItem(revista);

            // Crear miembro
            MiembroBiblioteca miembro = new MiembroBiblioteca("Ana López", "M123");
            biblioteca.registrarMiembro(miembro);

            // Mostrar catálogo
            biblioteca.mostrarCatalogo();

            // Agregar ítems al registro de préstamo
            miembro.getRegistro().agregarItem(libro);
            miembro.getRegistro().agregarItem(revista);

            // Procesar préstamo
            MetodoNotificacion email = new NotificacionEmail("ana.lopez@email.com");
            biblioteca.procesarPrestamo(miembro, email);

            // Mostrar catálogo actualizado
            biblioteca.mostrarCatalogo();

        } catch (BibliotecaException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}