Last active
June 10, 2022 21:13
-
-
Save flbulgarelli/ef546da56968d24c0284d8e43152946a to your computer and use it in GitHub Desktop.
QMP6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//1 - Sugerencia diaria | |
//Asumamos que habíamos modelado | |
class Sugerencia{ | |
List<Atuendo> atuendos | |
} | |
//Podemos hacer | |
public class AsesorDeImagen implements GeneradorSugerencias { | |
private Sugerencia listaAtuendos; | |
} | |
//--> Ojo a nivel instancias | |
class Usuario { | |
//(...) | |
Sugerencia sugerenciaDiaria; | |
Sugerencia getSugerenciaDiaria(){...} | |
} | |
//-> Hay gente que guardó listas de sugerencias. No parece tener mucho sentido (no sé si estaba de antes) (?) | |
//2 - Disparar calculo diario | |
//El empleado... | |
class Empleado { | |
ServicioMeteorologico servicioMeteorologico | |
List<Usuario> usuarios | |
calcularSugerenciasDiarias() { | |
usuarios.forEach(usuario => usuario.calcularSugerenciaDiaria() | |
} | |
} | |
class Usuario { | |
//(...) | |
Sugerencia sugerenciaDiaria; | |
Sugerencia getSugerenciaDiaria(){...} | |
calcularSugerencia() { | |
//Cálculo de sugerencias, puede delegar en otros componentes | |
} | |
calcularSugerenciaDiaria() { | |
this.sugerenciaDiaria = calcularSugerencia() | |
} | |
} | |
//--- | |
class ListaUsuarios { | |
// Singleton | |
List<Usuario> usuarios | |
void calcularSugerencias() { | |
usuarios.forEach(usuario -> usuario.pedirSugerencia() ) | |
} | |
} | |
//---- | |
class RepositorioUsuarios{ | |
List<Usuario> usuarios; | |
List<Usuario> getUsuarios(){...} | |
} | |
//--> Podría ser un Singleton | |
class AsesorDeImagen { | |
(...) | |
RepositorioUsuarios repoUsuarios; | |
void calcularSugerenciasDiarias() { | |
repoUsuarios.getUsuarios().forEach(usuario -> usuario.calcularSugerenciaDiaria()) | |
} | |
} | |
//-> Ojo con meterse a hacer planificadores y cosas similares antes de tiempo | |
//3 Conocer últimas alertas | |
class Usuario { | |
//(...) | |
List<String> alertasActuales = new ArrayList<>(); | |
} | |
//-> Ojo que son únicas para todo el sistema | |
class ListaAlertas { | |
ServicioMeteorologico servicioMeteorologico; | |
Map<String, Object> alertas | |
} | |
//-> Ojo con acoplarse a la API | |
//----- | |
public class GestorDeAlertas { | |
ServicioMeteorologico servicioMeteorologico; | |
List<String> alertasActuales = new ArrayList<>(); | |
} | |
//-> Ojo con el nombre 'gestor' | |
//---- | |
public class RegistroAlertas { | |
ServicioMeteorologico servicioMeteorologico; | |
List<String> alertasActuales = new ArrayList<>(); | |
} | |
//-> Podria ser un objeto dedicado o no | |
//-> Ojo con strings | |
//----- | |
enum AlertaMeteorologica { | |
TORMENTA, | |
GRANIZO | |
} | |
class ServicioMeteorológico { | |
List<AlertaMeteorologica> alertasActuales = new ArrayList<>(); | |
} | |
//4 - Actualizar altertas periódicamente | |
public class RegistroAlertas { | |
List<AlertaMeteorologica> alertasActuales = new ArrayList<>(); | |
public void actualizarAlertas() { | |
this.alertasActuales = new ServicioMeteorologicoAccuWeather().getAlertasMeteorologicas(); | |
} | |
} | |
class ServicioMeteorologicoAccuWeather implements ServicioMeteorologico { | |
List<AlertaMeteorologica> adaptarListaDeAlertas(List<String> alertas) { | |
//convierto una lista de strings a una lista de los enums de mi dominio | |
} | |
List<AlertaMeteorologica> getAlertasMeteorologicas() { | |
AccuWeatherAPI apiClima = new AccuWeatherAPI(); | |
Map<String, Object> alertas = apiClima.getAlertas("Buenos Aires"); | |
return adaptarListaDeAlertas(alertas.get("CurrentAlerts")); | |
} | |
} | |
//-> Si no es posible hacer ese new, puedo inyectar el servicio meteorológico | |
//5+ - Acciones ante alertas | |
public class RegistroAlertas { | |
List<AlertaMeteorologica> alertasActuales = new ArrayList<>(); | |
public void actualizarAlertas() { | |
this.alertasActuales = new ServicioMeteorologicoAccuWeather().getAlertasMeteorologicas(); | |
this.realizarAccionesSobreAlertas(this.alertasActuales) | |
} | |
public void realizarAccionesSobreAlertas(alertas){ | |
new MailSender().send(...) | |
if(alertas.contains(AlertaMeteorologica.TORMENTA)){ | |
new NotificationService().notify("Lleva Paraguas") | |
}else if (alertas.contains(AlertaMeteorologica.GRANIZO)) { | |
new NotificationService().notify("No salgas en auto") | |
} | |
(...) | |
} | |
} | |
//-> Qué problemas hay? | |
//Definimos interfaces salientes para usar despues y nos despreocupamos por ahora | |
interface Correo{ | |
public enviarCorreo(Usuario user, String cuerpo); | |
} | |
interface Notificador{ | |
public notificar(String mensaje); | |
} | |
//Definimos la idea de interesados genéricos | |
public interface AccionConfigurable { | |
public void nuevasAlertasMeteorologicas() | |
} | |
public class RegistroAlertas { | |
List<AlertaMeteorologica> alertasActuales = new ArrayList<>(); | |
List<AccionConfigurable> accionesConfigurables = new ArrayList<>(); | |
public void actualizarAlertas() { | |
this.alertasActuales = new ServicioMeteorologicoAccuWeather().getAlertasMeteorologicas(); | |
this.realizarAccionesSobreAlertas(this.alertasActuales) | |
} | |
public void realizarAccionesSobreAlertas(List<AlertaMeteorologica> alertas){ | |
accionesConfigurables.forEach(accion -> accion.nuevasAlertasMeteorologicas()) | |
} | |
} | |
public class AccionDeMandarMail implements AccionConfigurable { | |
@Override | |
public void nuevasAlertasMeteorologicas() { | |
new Correo().enviarCorreo(???,"Hay nuevas alertas ") | |
} | |
} | |
//-> Falta el usuario | |
//-> Las acciones son configurables a nivel usuario | |
//Opcion A -> interesados en el registro | |
public interface AccionConfigurable { | |
public void nuevasAlertasMeteorologicas(); | |
public void suscribirUsuario(Usuario usuario); | |
public void desuscribirUsuario(Usuario usuario); | |
} | |
public class AccionDeMandarMail implements AccionConfigurable { | |
List<Usuario> usuariosInteresados = new ArrayList<>(); | |
@Override | |
public void nuevasAlertasMeteorologicas() { | |
usuariosInteresados.forEach(usuario-> new Correo().enviarCorreo(usuario.correoElectronico,"Hay nuevas alertas meteorológicas..." /*Imprimir las alertas sacadas del Gestor de Alertas*/)); | |
} | |
public void suscribirUsuario(Usuario usuario) { | |
usuariosInteresados.add(usuario); | |
} | |
public void desuscribirUsuario(Usuario usuario) { | |
usuariosInteresados.remove(usuario); | |
} | |
} | |
public class NotificadorAnteAlertas implements AccionConfigurable { | |
List<Usuario> usuariosInteresados = new ArrayList<>(); | |
public void nuevasAlertasMeteorologicas() { | |
if(RegistroAlertas.instance().getAlertasActuales().contains(AlertaMeteorologica.TORMENTA)){ | |
usuariosInteresados.forEach(usuario -> new Notificador().notificar("Sali con paraguas!")); | |
}else if(RegistroAlertas.instance().getAlertasActuales().contains(AlertaMeteorologica.GRANIZO)) { | |
usuariosInteresados.forEach(usuario -> new Notificador().notificar("No salgas en auto!")); | |
} | |
} | |
} | |
//-> Acoplamiento innecesario con el registro. No hace falta q sea singleton! | |
public class RegistroAlertas { | |
List<AlertaMeteorologica> alertasActuales = new ArrayList<>(); | |
List<AccionConfigurable> todasLasAccionesPosibles = new ArrayList<>(); | |
public void realizarAccionesSobreAlertas(List<AlertaMeteorologica> alertas){ | |
accionesConfigurables.forEach(accion -> accion.nuevasAlertasMeteorologicas(this)) | |
} | |
} | |
List<Usuario> usuariosInteresados = new ArrayList<>(); | |
public void nuevasAlertasMeteorologicas(RegistroAlertas registro) { | |
if(registro.getAlertasActuales().stream().contains(AlertaMeteorologica.TORMENTA)){ | |
usuariosInteresados.forEach(usuario -> new Notificador().notificar("Sali con paraguas!")); | |
}else if(registro.getAlertasActuales().contains(AlertaMeteorologica.GRANIZO)) { | |
usuariosInteresados.forEach(usuario -> new Notificador().notificar("No salgas en auto!")); | |
} | |
} | |
} | |
//-> Es medio rebuscado | |
//-> el regsitro deberia conocer a todas las acciones posibles y luego cada usuario suscribirse | |
//-> El registro es un objeto a nivel 'sistema' | |
//Opcion B -> Delegamos al usuario | |
public class RegistroAlertas { | |
List<AlertaMeteorologica> alertasActuales = new ArrayList<>(); | |
RepositorioUsuarios repoUsuarios; | |
public void actualizarAlertas() { | |
this.alertasActuales = new ServicioMeteorologicoAccuWeather().getAlertasMeteorologicas(); | |
this.realizarAccionesSobreAlertas(this.alertasActuales) | |
} | |
public void realizarAccionesSobreAlertas(List<AlertaMeteorologica> alertas){ | |
repoUsuarios.getUsuarios().forEach(usuario -> usuario.realizarAccionesSobreAlertas(alertas)) | |
} | |
} | |
class Usuario { | |
//(...) | |
List<AccionConfigurable> accionesConfigurables = new ArrayList<>(); | |
public void realizarAccionesSobreAlertas(List<AlertaMeteorologica> alertas){ | |
accionesConfigurables.forEach(accion -> accion.nuevasAlertasMeteorologicas(this)); | |
} | |
} | |
public interface AccionConfigurable { | |
public void nuevasAlertasMeteorologicas(Usuario usuario); | |
} | |
public class NotificadorAnteAlertas implements AccionConfigurable { | |
public void nuevasAlertasMeteorologicas(Usuario usuario) { | |
if(???.getAlertasActuales().contains(AlertaMeteorologica.TORMENTA){ | |
new Notificador().notificar("Sali con paraguas!"); | |
}else if(???.getAlertasActuales().contains(AlertaMeteorologica.GRANIZO) { | |
new Notificador().notificar("No salgas en auto!"); | |
} | |
} | |
} | |
//Nos faltan las alertas! | |
// No pasa naranja 😎 | |
class Usuario { | |
//(...) | |
List<AccionConfigurable> accionesConfigurables = new ArrayList<>(); | |
public void realizarAccionesSobreAlertas(List<AlertaMeteorologica> alertas){ | |
accionesConfigurables.forEach(accion -> accion.notficarActualizacionDeAlertas(this, alertas)); | |
} | |
agregarAccion(AccionConfigurable accion){ | |
this.accionesConfigurables.add(accion) | |
} | |
removerAccion(AccionConfigurable accion){ | |
this.accionesConfigurables.remove(accion) | |
} | |
} | |
public interface AccionConfigurable { | |
public void nuevasAlertasMeteorologicas(Usuario usuario, List<AlertaMeteorologica> alertas); | |
} | |
public class NotificadorAnteAlertas implements AccionConfigurable { | |
public void nuevasAlertasMeteorologicas(Usuario usuario, List<AlertaMeteorologica> alertas) { | |
if(alertas.contains(AlertaMeteorologica.TORMENTA)){ | |
new Notificador().notificar("Sali con paraguas!"); | |
}else if(alertas.contains(AlertaMeteorologica.GRANIZO)) { | |
new Notificador().notificar("No salgas en auto!"); | |
} | |
} | |
} | |
//-> Type test medio raro | |
//-> Logica repetida al enviar la notificacion | |
class NotificadorAnteAlertas implements AccionConfigurable { | |
Map<AlertaMeteorologica, String> mensajes = {...} | |
nuevasAlertasMeteorologicas(alertasNuevas, usuario) { | |
alertasNuevas.forEach(alerta -> | |
new Notificador().notificar(mensajes.get(alerta)) | |
) | |
} | |
} | |
// Sin el if | |
class NotificadorAnteAlertas implements AccionConfigurable { | |
nuevasAlertasMeteorologicas(alertasNuevas, usuario) { | |
alertasNuevas.forEach(alerta -> | |
new Notificador().notificar(alerta.getMensaje()) | |
) | |
} | |
} | |
enum Alerta{ | |
TORMENTA(){ | |
getMensaje(){ | |
return "lleva paraguas" | |
} | |
} | |
} | |
//-->Puede andar pero --> OJO el mensaje de la notificacion esta 100% definido SOLO por la alerta? | |
//--> Si el mensaje de notificacion es uno, pero el q se manda x mail o whatsapp es otro? | |
//--> Tal vez el if no sea tan malo, aparte nos dijeron que no cambiaba eso | |
//Y separar los interesados? | |
class TormentaObserver implements AccionConfigurable { | |
nuevasAlertasMeteorologicas(alertasNuevas, usuario) { | |
if(alertas.contains(AlertaMeteorologica.TORMENTA)){ | |
new Notificador().notificar("Sali con paraguas!") | |
} | |
} | |
} | |
class GranizoObserver implements AccionConfigurable { | |
nuevasAlertasMeteorologicas(alertasNuevas, usuario) { | |
if(alertas.contains(AlertaMeteorologica.GRANIZO)){ | |
// Ojo con cosas del estilo usuario.enviarNotificacion -> Puede ser pasamanos | |
new Notificador().notificar("No salgas en auto!"); | |
} | |
} | |
} | |
//-> Interesados q reaccionan ante una sola alerta -> raro, mezcla eventos con interesados | |
//---> Habria q ver bien q quiero | |
//Antes de seguir: Cuál es el evento? ----> La actualizacion de las alertas -> el mensaje `nuevasAlertasMeteorologicas` | |
//Quiénes son los interesados? -----> Las acciones configurables | |
//Qué son Tormenta/Granizo? ----> Son como un "parametro" del actualizacion de las alertas | |
//Opción Alternativa: Ver TORMENTA/GRANIZO como eventos separados | |
//Observado | |
class Usuario { | |
//(...) | |
List<AccionConfigurable> accionesConfigurables = new ArrayList<>(); //Interesados-Observers | |
public void realizarAccionesSobreAlertas(List<AlertaMeteorologica> alertas){ | |
//El type test lo podemos resolver con las estrategias que ya conocemos | |
if(alertas.contains(AlertaMeteorologica.TORMENTA)){ | |
accionesConfigurables.forEach(accion -> accion.nuevaAlertaTormenta(this)); | |
}else if(alertas.contains(AlertaMeteorologica.GRANIZO)) { | |
accionesConfigurables.forEach(accion -> accion.nuevaAlertaGranizo(this)); | |
} | |
} | |
} | |
public interface AccionConfigurable { //Eventos | |
public void nuevaAlertaTormenta(Usuario usuario); | |
public void nuevaAlertaGranizo(Usuario usuario); | |
} | |
class NotificadorAnteAlertas implements AccionConfigurable { | |
nuevaAlertaTormenta(usuario) { | |
new Notificador().notificar("Lleva paraguas") | |
} | |
nuevaAlertaGranizo(usuario) { | |
new Notificador().notificar("No salgas en auto") | |
} | |
} | |
class RecalculadorSugerencias implements AccionConfigurable { | |
nuevaAlertaTormenta(usuario) { | |
usuario.calcularSugerenciaDiaria() | |
} | |
nuevaAlertaGranizo(usuario) { | |
usuario.calcularSugerenciaDiaria() | |
} | |
} | |
//Si en general los interesados hacen cosas diferentes para cada alerta, | |
//entonces tiene sentido ver a las alertas como eventos separados | |
//---> Los interesados se interesan en (todos) los eventos del observado | |
//----> Si quiero separar ya es otro tema (tal vez x listas mejor) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment