Agregado Lista de Correo II

Proyecto para descargarse

http://svn2.xp-dev.com/svn/utn-tadp-projects/listacorreo.agregados.domain/ siguiendo este instructivo

Posibilidades de moderación

Además de tener como opciones de envío:
a. Abierto
b. Sólo los miembros pueden enviar un mensaje

Se quiere agregar estas posibilidades:
c. Los mensajes de no-miembros son moderados.
d. Los miembros nuevos son moderados. Se considera que un usuario es nuevo cuando tiene menos de un mes de suscripto a la lista. Ejemplo: Laura Iturbe se suscribe a la lista el 01/05/2011, hasta el 01/06/2011 será un usuario nuevo y el 02/06 ya no.
e. Moderación de usuarios específicos: se cargará una lista con los usuarios a moderar.

Al recibir un mensaje de una dirección moderada el sistema manda el mail primero a los moderadores, con un encabezado especial. El mensaje queda en espera hasta que un moderador aprueba y entonces este mensaje se envía. Si en 5 días nadie aprueba el mensaje, éste debe ser eliminado.

Pensarlo como opciones combinadas (podríamos tener alguna de las opciones o varias superpuestas)

Qué queremos lograr

Poder combinar opciones de moderación/validación, de manera de tener:

  • Moderación para miembros nuevos y específicos
  • Moderación para no-miembros y miembros nuevos
  • O bien moderar usuarios específicos y permitir que sólo los miembros puedan enviar mensajes

La primera opción podría ser tener una colección de strategies, pero nuevamente tenemos que distinguir:

  • si el mensaje puede enviarse
  • si el mensaje debe moderarse

Esto ya lo hemos visto anteriormente, otra opción es hablar con un objeto que termine implementando la moderación/validación/envío del mensaje.
La única restricción es que compartan todos la misma interfaz:

Env%C3%ADo%20de%20Mensajes%20Moderados0.png

¿Un solo objeto?

Sí, uno solo, lo que pasa es que vamos a interceptar código antes de enviar un mensaje:

  • en particular, tendremos envíos comunes, a ese tipo de envío lo llamamos EnvioMail. Como no queremos probar la parte tecnológica que manda mail vamos a implementar una subclase mock de EnvioMail, esto significa que lo único que hace es imprimir por consola cierta información que equivaldría a "mandar un mail":
Env%C3%ADo%20de%20Mensajes%20Moderados1.png

A continuación, algo de código:

>>EnvioMail
    public void enviarMensaje(ListaCorreo listaCorreo, Mensaje mensaje) {
        mensaje.enviar(listaCorreo);
        this.enviarMail(listaCorreo, mensaje);
    }

    // Template method
    public abstract void enviarMail(ListaCorreo listaCorreo, Mensaje mensaje);

>>EnvioMailMockeado
    // Implementación del Template method
    public void enviarMail(ListaCorreo listaCorreo, Mensaje mensaje) {
        System.out.println("Enviando mensaje " + mensaje);
    }

Intercepción de código

Ahora vamos a modelar un objeto que intercepte el envío de mail. Vamos a poder hacerle cosas:

  • antes y
  • después del envío del mail

Pero no vamos a encargarnos de mandar el mail propiamente, eso vamos a delegarlo en un objeto EnviarMail.
O sea, sólo vamos a codificar la moderación, de manera que para tener una lista que modere usuarios nuevos tendremos estos objetos:

ListaCorreo.ModerarUsrNuevos.png

Entonces vamos a definir una clase abstracta que va a servir para moderar los mensajes, esta clase abstracta funciona como Decorator:

Env%C3%ADo%20de%20Mensajes%20Moderados2.png

Mostramos con código cómo quedaría:

>>EnvioEspecial
    @Override
    public void enviarMensaje(ListaCorreo listaCorreo, Mensaje mensaje) {
        this.preEnviarMensaje(listaCorreo, mensaje);
        this.getTipoEnvio().enviarMensaje(listaCorreo, mensaje);
        this.postEnviarMensaje(listaCorreo, mensaje);
    }

    public abstract void preEnviarMensaje(ListaCorreo listaCorreo, Mensaje mensaje);

    public abstract void postEnviarMensaje(ListaCorreo listaCorreo, Mensaje mensaje);

Lo que estamos haciendo es dejar la puerta abierta para interceptar código antes / después del envío del mensaje, y delegar en el tipo de envío el envío del mensaje propiamente.

Lo bueno es que este decorator nos sirve tanto para verificar que sólo los usuarios puedan enviar mensajes como para moderar el envío.

Moderación de un mensaje

Ahora vamos a agregar una subclase de EnvíoEspecial, que trabaje sobre las moderaciones:

Env%C3%ADo%20de%20Mensajes%20Moderados.png

Y lo implementamos:

>>EnvioModerado
    @Override
    public void preEnviarMensaje(ListaCorreo listaCorreo, Mensaje mensaje) {
        if (this.debeModerar(listaCorreo, mensaje.getUsuario())) {
            listaCorreo.agregarMensajeModerado(mensaje.copy());
            mensaje.moderar(listaCorreo);
        }
    }

    public abstract boolean debeModerar(ListaCorreo listaCorreo, Usuario usuario);

    @Override
    public void postEnviarMensaje(ListaCorreo listaCorreo, Mensaje mensaje) {

    }

Tenemos la opción de moderar el mensaje antes de enviarlo. Para ello:
  • tenemos que generar una copia de ese mensaje y guardarlo en la lista de mensajes pendientes del grupo de correo
  • a partir de aquí podemos "moderar" el mensaje, que consiste en cambiar la lista de destinatarios (de los miembros de la lista a los moderadores) y agregarle el prefijo "MODERATE" al asunto.

Para cambiar las opciones de moderación, sólo tenemos que implementar subclases de EnvioModerado redefiniendo el método debeModerar. Mostramos un ejemplo:

>>EnvioModerarUsuariosNuevos
    public boolean debeModerar(ListaCorreo listaCorreo, Usuario usuario) {
        return usuario.esNuevo();
    }

Combinación de moderaciones

El único problema que podemos tener es si combinamos opciones de moderación que no son excluyentes, porque eso puede llevarnos a que en:

>>EnvioModerado
    public void preEnviarMensaje(ListaCorreo listaCorreo, Mensaje mensaje) {
        if (this.debeModerar(listaCorreo, mensaje.getUsuario())) {
            listaCorreo.agregarMensajeModerado(mensaje.copy());
            mensaje.moderar(listaCorreo);
        }
    }

nos agregue dos veces el mismo mensaje a moderar, además de que en el asunto aparezca dos veces "MODERATE:".

Si vamos a decorar comportamiento, es ideal que esos comportamientos no tengan efecto colateral entre sí, dado que podemos tener problema con el orden o con el estado de los objetos. Para este caso en el cual no podemos estar seguros de que no se moderen dos veces el mismo mensaje (porque lo pueden moderar específicamente a un usuario nuevo y tener ambas moderaciones activas), tenemos que hacer una pequeña modificación:

>>EnvioModerado
    public void preEnviarMensaje(ListaCorreo listaCorreo, Mensaje mensaje) {
        if (!mensaje.estaModerado() && this.debeModerar(listaCorreo, mensaje.getUsuario())) {
            listaCorreo.agregarMensajeModerado(mensaje.copy());
            mensaje.moderar(listaCorreo);
        }
    }
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License