EJERCICIO POO

Iniciado por joseba11, 2 Mayo 2020, 21:27 PM

0 Miembros y 1 Visitante están viendo este tema.

joseba11

Tengo que entregar este ejercicio y me resulta muy difícil, no entiendo muchas de las cosas y mi profesora no es precisamente muy amigable. Si alguien me pudiera ayudar le estaría eternamente agradecido, es muy importante que lo entregue. Por aquí os dejo el ejercicio. MUCHAS GRACIAS.



Previo. Gestión de fechas.
- Para representar las fechas utilizaremos la clase java.time.LocalDate, que
implementa una fecha sin información de la zona horaria de acuerdo al sistema de
calendario ISO-8601, en el formato (por defecto) de año-mes-día, por ejemplo,
2019-10-24.
- La clase LocalDate no dispone de constructores. Para crear objetos se utiliza el
método de clase of, que recibe como parámetro el año, mes (como un entero o un valor
del enumerado Month) y día. Por ejemplo:
LocalDate fecha = LocalDate.of(2019, 10, 24);
LocalDate fecha = LocalDate.of(2019, Month.OCTOBER, 24);
- El método de clase now crea un objeto con la fecha actual.
- Para comparar fechas están disponibles los métodos isAfter, isBefore e
isEqual.
- Los objetos LocalDate son inmutables, por lo que cualquier operación de cambio de
fecha (suma/resta de años, días o meses) devuelve un nuevo objeto con el resultado.
Previo. Generación de números aleatorios.
- La clase java.util.Random permite obtener números aleatorios.
- El método nextInt(cotaSuperior) de esta clase retorna un entero generado
aleatoriamente entre 0 y cotaSuperior (no incluido).
- Está disponible un ejemplo de uso en la sesión 5 de las prácticas de laboratorio
(máquina tragaperras).
Previo. Lectura de datos de la consola.
- La clase java.util.Scanner puede utilizarse para leer datos de la consola.
- El método nextLine retorna el texto introducido por el usuario hasta la pulsación
del retorno de carro.
Scanner scanner = new Scanner(System.in);
System.out.println("Introduce tu nombre: ");
String nombre = scanner.nextLine();
// ...
scanner.close();
2/5
Queremos desarrollar una biblioteca de código a cargo de realizar la verificación del acceso
de un usuario a una aplicación, lo que comúnmente se denomina "login".
1. Verificadores
Un verificador es un tipo de datos encargado de comprobar que las credenciales que
proporciona un usuario para el acceso a un sistema son correctas. Antes de comenzar la
presentación de este tipo de datos, se presenta el concepto usuario.
Un usuario se caracteriza por las siguientes propiedades (consultables):
- login: cadena que identifica al usuario en el sistema. Esta propiedad no puede ser
modificada una vez ha sido establecida en el constructor.
- fecha último acceso: representa la última vez que el usuario realizó un acceso correcto
en el sistema.
- password: cadena que representa la contraseña de acceso.
- historial de passwords: conjunto que almacena las contraseñas de acceso que ha
utilizado el usuario.
En la construcción de un usuario se establecen las propiedades login y password.
Inicialmente el historial de passwords está formado únicamente por la contraseña que se
proporciona en la construcción. Además, se establece como fecha de último acceso el
momento de la creación.
La funcionalidad que ofrece este tipo de datos es la siguiente:
- Modificar password: esta operación tiene dos parámetros, el password actual y el nuevo
que queremos establecer. La modificación del password se hará efectiva si el password
actual es correcto y la nueva contraseña no forma parte del historial de passwords. Si se
cumplen las dos condiciones, se actualiza la propiedad password y la nueva contraseña
se añadirá al historial de passwords. La operación retorna un valor booleano indicando si
se ha realizado la modificación.
- Validar: esta operación se encarga de comprobar si la contraseña proporcionada como
parámetro coincide con la contraseña del usuario. La operación retorna un valor
booleano indicando si la validación ha sido correcta.
- Establecer la fecha de último acceso. Esta operación no tiene parámetros. El objetivo es
establecer como fecha de último acceso la fecha actual.
Un verificador representa el tipo de datos encargado de verificar la identificad de un usuario
en el acceso a un sistema. Para ello se ofrece un proceso de verificación en dos pasos. En el
primer paso (loginPaso1) se comprueba que las credenciales del usuario (login y password)
sean correctas. Si se supera el primer paso, el usuario deberá superar un desafío, esto es,
debe dar respuesta a una petición. En el segundo paso, el usuario establecerá la respuesta al
desafío propuesto (loginPaso2). Los dos pasos del proceso están vinculados a través de un
token. Si el primer paso es superado, se obtiene un token que deberá utilizarse para
establecer la respuesta al desafío. Esta funcionalidad se describe con detalle más adelante.
3/5
Las propiedades de los verificadores son:
- usuarios: colección de usuarios que gestiona.
Requisito: la colección será representada como un mapa, donde la clave será la
propiedad login del Usuario y el valor asociado el objeto Usuario. El método de consulta
de la propiedad retornará una colección de usuarios (los valores del mapa).
- petición del desafío: es una cadena de texto con la información necesaria para que el
usuario responda al segundo paso del proceso de verificación. Por ejemplo, "Introduzca
el día del mes de su último acceso". Esta propiedad no cambia una vez establecida en la
construcción.
Un verificador se construye estableciendo la petición del desafío. Inicialmente la colección
(mapa) de usuarios es vacía.
La funcionalidad que ofrecen los verificadores es la siguiente:
- Añadir usuarios. Esta operación tiene como propósito añadir nuevos usuarios al conjunto
de usuarios gestionado por el verificador. Tiene como parámetro un argumento de
tamaño variable de tipo Usuario.
- Borrar un usuario. El método tiene como parámetro el objeto usuario que se desea
eliminar del verificador. Retorna un valor booleano informando si la acción ha sido
efectiva.
- Primer paso del proceso de verificación (loginPaso1). Esta operación tiene como
parámetros dos cadenas que representan las credenciales del usuario: login y password.
La operación retorna una cadena (token, necesario para el paso 2). Es requisito para
implementar esta operación aplicar el concepto de método plantilla. Los pasos que
realiza esta operación son los siguientes:
• Comprueba que el usuario esté incluido en el mapa de usuarios. Si no está incluido,
se retorna un valor nulo (no hay token).
• Comprueba que las credenciales sean válidas, es decir, que el password sea válido
para el usuario. Si no es así, retorna un valor nulo.
• Genera el token que será retornado por la operación.
Nota: utiliza UUID.randomUUID().toString() para obtenerlos.
• Genera la respuesta correcta al desafío (cadena). El modo de generar esta respuesta
depende del tipo de verificador (se explica más adelante).
• Registra en un mapa de desafíos la asociación entre el token y la respuesta correcta.
Nota: el mapa de desafíos es un atributo de implementación, es decir, no es una
propiedad del tipo de datos. Por tanto, no debe ofrecerse un método para su
consulta.
• Por último, retorna el token.
4/5
- Segundo paso del proceso de verificación (loginPaso2). Esta operación se encarga de
finalizar el proceso de verificación. Los parámetros de la operación son: una cadena que
representa un token (obtenido en el paso 1) y una cadena con la respuesta del usuario al
desafío. La operación retorna un valor booleano indicando si el proceso de verificación
ha sido superado. Los pasos que realiza esta operación son los siguientes:
• Comprueba que el token se encuentre registrado en el mapa de desafíos. Si no es así,
retorna el valor falso (no existe el desafío).
• Comprueba que la respuesta del usuario sea correcta. Para ello, se obtiene la
respuesta correcta asociada al token del mapa de desafíos y comprueba si coinciden.
Si no son iguales, se elimina el token del mapa de desafíos y se retorna el valor falso
(no supera el desafío).
• Una vez superadas las comprobaciones anteriores, el desafío ha sido superado. Se
elimina la entrada asociada al token del mapa de desafíos y finaliza retornando el
valor verdadero.
2. Tipos de verificadores.
Se ofrecen dos tipos de verificadores: verificador blacklist y verificador por código.
Un verificador blacklist se caracteriza por tener una colección de usuarios (logins de
usuarios) que han sido bloqueados en el sistema. Para la gestión de esta colección se
ofrecen un par de operaciones para darlos de alta y baja. Por tanto, no podrá superarse el
primer paso del proceso de verificación (loginPaso1) si el usuario ha sido bloqueado.
Por otra parte, un verificador blacklist tiene como petición del desafío: "Introduzca el
número del mes de su último acceso". Por tanto, la respuesta correcta al desafío será el
texto que corresponda al día del mes del último acceso del usuario al sistema.
Nota: la clase java.time.LocalDate permite consultar el día del mes de una fecha con el
método getMonthValue.
Un verificador por código tiene como petición del desafío: "Introduzca el número que ha
recibido por SMS". La respuesta correcta al desafío es un único valor que se genera de forma
aleatoria entre 0 y 999 (ambos incluidos).
Nota 1: utiliza la clase java.util.Random para la generación de número aleatorios.
Nota 2: en un sistema real el verificador por código enviaría el número aleatorio al usuario a
través del correo electrónico o como SMS al número de móvil. Con el fin de poder probar la
aplicación, se mostrará el código generado por la salida de error (System.err).
Por último, un verificador por código limita el número de intentos para la superación del
paso 2 de la verificación. Este límite se establece en la construcción y no puede cambiar. Si
un usuario falla al intentar superar el desafío el número de veces fijado por ese límite, el
token será eliminado del mapa de desafíos.
5/5
3. Copia de verificadores.
Implementa el método clone en la jerarquía de clases que representan los verificadores
siguiendo las recomendaciones de la asignatura y según la semántica de los tipos de datos.
En este sentido, debe tenerse en cuenta lo siguiente:
- Es necesario evitar los casos de aliasing que no sean correctos, en especial, los
relativos a las colecciones.
- Siempre interesa redefinir el método clone en los descendientes, aunque solo sea
para aplicar la regla covariante.
- La copia de un verificador no debe tener información sobre el proceso de verificación
en dos pasos. Así pues, solo se copiará la colección de usuarios.
- La copia de un verificador blacklist no debe tener ningún usuario bloqueado.
4. Programa
Para mostrar la información en el programa es necesario implementar el método toString
en todos los tipos de datos.
Implementa el siguiente programa:
- Crea un usuario con login "fperez" con password "lechemerengada". Modifica el
password del usuario anterior estableciendo "cr7comeback"
- Crea un usuario con login "mlama" con password "tururu".
- Crea un verificador blacklist y un verificador por código con un máximo de 5 intentos.
- Añade los usuarios a los verificadores.
- Declara y construye una lista de verificadores. Añade los verificadores anteriores.
- Recorre la lista de verificadores: si el verificador es de tipo blacklist, añade el usuario
"mlama" como usuario bloqueado.
- Recorre la lista de verificadores:
o Solicita por la consola el login y password del usuario.
Nota: utiliza la clase java.util.Scanner para leer información de la consola.
o Con las credenciales anteriores, realiza el primer paso de verificación.
o Si el primer paso ha sido superado:
▪ Obtén del verificador la petición del desafío y muéstrala por la consola.
▪ Solicita por la consola la respuesta al desafío.
▪ Con el token obtenido en el paso 1 y la respuesta, realiza el segundo paso
del desafío. Muestra por la consola el resultado.
- Declara y construye una nueva lista de verificadores llamada copias.
- Recorre la primera lista de verificadores y para cada elemento obtén una copia y
guárdala en la lista copias.
- Recorre la lista con las copias y para cada verificador muestra su información por la
consola (toString).

K-YreX

De verdad piensas que llegando aquí y soltando un copia-pega de tu ejercicio, alguien te lo va a dar resuelto??
Empieza a hacer el ejercicio y saca todo lo que puedas por ti mismo. Cuando no sepas avanzar más, revisa tus apuntes u otros materiales (pdfs, vídeos,...) que puedes encontrar en Internet. Y cuando llegues a un problema que no puedas solucionar ni usando todos esos materiales de los que puedes disponer, coloca el/los fragmento/s de código necesarios (entre etiquetas de Código GeSHi) y entonces alguien te ayudará a resolver ese problema concreto; pero nadie te va a hacer el ejercicio entero...
Suerte.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;