Parcial resuelto Consultify de 2020 #293
-
Buenas gente que tal, un compañero me compartio un parcial que tomaron el año pasado, nose en que curso la verdad, pero bueno.. comparto mi resolucion para comparar con ustedes (si lo ve algun ayudante/profesor para decir algo determinante, se re contra agradece tambien para saber si esta mas o menos bien la resolucion ) se aceptan todo tipo de comentarios enunciado: https://docs.google.com/document/d/1PWHfhoOQbliv_dQrTWNMqDcxL1Q5_6YKMTFEcypUeQA/edit?usp=sharingresolucion:---------------------------------------------------
1. 'buscar una consulta en base a un link'
/* singleton */
class RepositorioDeConsultas{
List<Consulta> consultas;
.. // y demas funciones de un repositorio
addConsulta::();
removeConsulta::();
..
Consulta obtenerConsulta(String link){
return this.consultas.findFirst(consulta -> consulta.tieneLink(link));
}
}
abstract class Consulta{
String link;
LocalDateTime periodoDeValidez;
boolean tieneLink(String link){
return this.link.equals(link);
}
}
---------------------------------------------------
2. 'saber si una consulta es accesible'
unaConsulta.esAccesible();
Consulta>>
/* podria ir en el constructor tambien */
void setPeriodoDeValidez(LocalDateTime fecha){
this.periodoDeValidez = fecha;
}
void pausar(){ // despausar lo mismo
this.pausada = true;
}
/*podria ir mejor logica, tal vez fijandose si quedan 10 minutos, o algo asi
pero el enunciado no hace enfasis */
boolean esAccesible(){
return LocalDateTime.now().isBefore(this.periodoDeValidez) && !this.pausada;
}
---------------------------------------------------
8. 'Queremos poder pausar una consulta, el inicio y fin no cambia ya que el usuario podrá reactivarla cuando lo desee. Para esto vamos a tener varios criterios de pausado:
Hasta cierta fecha, cuando se cumple dicha fecha se despausa.
Indefinido, el usuario va a decidir despausarla.
Cuando se haya llegado a un cierto número de respuestas se pausa'
User/Admin/{}>>
void pausar(Consulta consulta, CriterioPausa criterio)
criterio.pausarConsulta(consulta);
interface CriterioPausa{}>>
void pausarConsulta();
class CriterioFecha implements CriterioPausa{}>>
LocalDateTime fechaLimite;
void pausarConsulta(Consulta consulta)
if (LocalDateTime.now().isAfter(this.fechaLimite)){
consulta.pausar();
}else{
consulta.despausar();
}
class CriterioCuandoYoQuiera implements CriterioPausa{}>>
void pausarConsulta(Consulta consulta)
consulta.pausar();
class CriterioMaximasRespuesta implements CriterioPausa{}>>
int maximasRespuestas;
void pausarConsulta(Consulta consulta)
if (consulta.getRespuestas() >= maximasRespuestas)
consulta.pausar();
---------------------------------------------------
3. 'crear una encuesta' y 4. 'Responder una encuesta, verificando: que la pregunta fue respondida de forma adecuada'
y 7. 'Responder un formulario, verificando:
que todas las preguntas obligatorias hayan sido respondidas
que todas las preguntas con valores enumerados estén dentro de las opciones.
'
/*a pesar de que la construccion de una encuesta es compleja,
con el builder gano mas que en eso, en el sentido de que
todas las encueestas intanciadas son validas, y se que
tienen una pregunta cerrada. entonces gano en robustez */
Encuesta encuesta = new EncuestaBuilder()
.setLink()
.setPeriodoDeValidez()
.setPregunta()
.build()
EncuestaBuilder>>
EncuestaBuilder setPregunta(Pregunta pregunta){
if (pregunta.esAbierta){
throw new Exception("las encuestas solo pueden tener preguntas cerradas")
}
this.pregunta = pregunta;
return this;
}
interface Pregunta{
boolean esAbierta();
boolean esObligatoria();
void setObligatoria();
void responder();
}
/* el enunciado da a entender que hay una diferenciacion entre
las preguntas de texto libre y las que tienen opciones , sean 2 (booleanas)
o sean varias (multivaluada)' */
abstract class MultiValuada implements Pregunta{}>>
List<String> opciones;
String correcta;
boolean obligatoria;
void responder(Opcion opcion){
if (this.esObligatoria && opcion.getString().equals("")) //fail fast
throw new ObligatoriaException("la respuesta es obligatoria")}
if (!opciones.contains(opcion)){} //fail fast
throw new RespuestaInvalidaException("debe responder una de las opciones en la lista")
this.opciones.get(opcion).elegir(); //aumenta el contador de elecciones
}
boolean esAbierta(){ return false}
}
class Booleana extends MultiValuada{}>>
/* limito en el constructor que solametne estas sean las opciones, not bad */
public Booleana(){
this.opciones = [new Opcion("SI") ,new Opcion("NO") ]
}
}
class Multiple extends MultiValuada{}>>
public Multiple(List<Opcion> opciones){
this.opciones = opciones ]
}
}
class TextoLibre implements Pregunta{
String correcta;
String respuesta;
public TextoLibre(String pregunta);
void responder(String rta){
if (this.esObligatoria && rta.equals("")) //fail fast
throw new ObligatoriaException("la respuesta es obligatoria")}
respuesta = rta;
}
}
class Opcion{}>>
String opcion;
int elecciones=0
public Opcion(String opcion){
elecciones = 0;
}
void elegir(){
elecciones++
}
---------------------------------------------------
5. 'Saber el resultado de una encuesta: cantidad de elecciones para cada opción.'
/* simplemente se reduce a tener un getter, puesto que cada opcion tiene su
contador y sabes cuantas veces la eligieron, ahora si la queres en otro formato bueno
te puedo hacer un parser, hacerlo en json, en csv, lo que quieras.. pero no creo
que sea el objetivo de este requerimiento */
Encuesta>>
List<Opcion> resultados(){
return this.opciones;
}
---------------------------------------------------
6. 'Crear un formulario'
/* no hace falta un builder puesto que el formulario
puede tener cualquier clase de pregunta */
class Formulario extends Consulta{}>>
List<Pregunta> preguntas;
public Formulario(List<Pregunta> preguntas);
---------------------------------------------------
9. 'Queremos que cada vez que se finaliza el periodo de una encuesta,
si es que está así configurado, se envíen los resultados de la misma
a todos los que participaron mediante el medio de comunicación que
indique el siguiente componente.
'
/* implemento un adapter tal que permita agregar componentes a futuro
por ejemplo wsp, podria hacer simplemente un
class EnviadorWsp implements EnviadorNotificacion
y ya deberia cumplir con el contrato de mi enviador de notificacion, convirtiendose
en un adapter */
interface EnviadorDeNotificacion{
public void enviar(String from, SuscriptorDTO suscriptor, String contenido);
}
class EnviadorDeMail implements EnviadorDeNotificacion{
public void enviar(String from, SuscriptorDTO suscriptor, String contenido){
MailSender mailSender = new MailSender()
int status = mailSender.send(from, to, contenido)
if (status!=1)
throw new NoSeEnvioELMailException("configurar puerto qcyo");
else
suscriptor.notifyByMail() ????????????????????????????
}
}
class EnviadorDeSMSTelegram implements EnviadorDeNotificacion{
public void enviar(String from, SuscriptorDTO suscriptor, String contenido){
TelegramSender telegramSender = new TelegramSender()
telegramSender.enviar(to, contenido);
suscriptor.notifyByTelegram();
}
}
/*esto no se entiende mucho, como que me dan la clase, pero nunca
me habla de bien como se maneja, ni en donde viven estos suscriptores,
ni nada, entonces propongo que cada encuesta (podria ponerlo en la consulta generica tmb)
tenga su lista de suscriptores */
class Encuesta{
List<SuscriptorDTO> suscriptores;
}
Encuesta>> void enviarResultados(EnviadorDeNotificacion enviador){
//podria programarse con cron para que se ejecute cada minuto y vea la fecha actual
// y la de la encuesta
if (LocalDateTime.now().equals(getPeriodoDeValidez()))
for (SuscriptorDTO sub: suscriptores){
try{
enviador.enviar("from", sub.getMail(), this.getResultados())
}
catch NoSeEnvioELMailException{
continue; // podria printear un mensaje de aviso que no se le envio a X suscriptor
// pero esto es para que no se corte el envio porque a uno no se le envio.
}
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hola @guidoenr! Te comento un par de cosas que note de un vistazo rápido, puede que me falten algunas.
La parte de buscar las encuestas y filtrarlas, podes codificarla, porque ahí vas a interacturar con el repositorio, y tal vez aparezca un mensaje de dominio en consulta para saber si esta terminada, entonces aparecen nuevas cosas.
Esto es medio raro, es una fecha si es igual a un periodo, las fechas deberían ser solo iguales a fechas. Tal vez debería ser un mensaje al fin del periodo que te diga si la fecha ya paso o algo así.
Entonces lo que tenes que hacer es guardate el mail cuando alguien conteste una consulta y con eso vas a poder unir los dos mundos. Con el suscriptorDTO que te da vas a poder saber que medios de notificación usa, fijate que tiene 2 mensajes que devuelven un booleano (notifyByMail / notifyByTelegram() ) Y con eso podes jugar un poco mas y tener un adapter que en vez de devolverte un suscriptordto te devuelva un suscriptor tuyo con objetos medio de notificación parecidos a los que hiciste . Bueno, espero que te sirva 🤯 |
Beta Was this translation helpful? Give feedback.
Hola @guidoenr!
Te comento un par de cosas que note de un vistazo rápido, puede que me falten algunas.
Manejo link: Ok
Manejo accesible con pausado:
Esta parte tiene un problema modelarlo con estado, que solo te va a marcar como pausada si la condición se esta dando en el momento que la ejecutaste.
El usuario lo que hace es setea el criterio, luego el pausar se puede resolver en la consulta preguntandole al criterio que seteo el admin y se retorna lo que calcula la estrategia de pausado en base al estado actual de la consulta.
Para hacerlo asi vas a tener que modelar un criterio que represente que el usuario no le configuro ningun criterio (sirve también para despausarla)
Encuentas …