Skip to content

Mejora: Implementar el patron Builder en MailManager para mejorar la extensibilidad #116

Description

@pepinxd28-glitch

Hola @jzyong,

En primer lugar, gracias por mantener este excelente repositorio.

Como parte de un análisis académico de arquitectura de software[cite: 1], nuestro equipo revisó el proyecto y encontró una gran oportunidad para mejorar la clase com.jzy.game.engine.mail.MailManager aplicando el patrón de diseño Builder[cite: 1].

La Situación Actual

En el método sendTextMail, la clase actualmente maneja tanto la construcción del objeto complejo MimeMessage como su transmisión. Esto crea un acoplamiento fuerte. Notamos que la línea 95 (// message.setContent(context, "text/html;charset=utf-8");) está comentada, lo cual evidencia que agregar soporte dinámico para HTML o archivos adjuntos actualmente requiere modificar el método principal, violando el Principio Abierto/Cerrado (OCP)[cite: 1].

Solución Propuesta

Sugerimos extraer la lógica de creación del mensaje a una clase dedicada MimeMessageBuilder. Esto permite construir el correo electrónico paso a paso y deja a MailManager con la única responsabilidad de transmitirlo.

Aquí está la implementación sugerida[cite: 1]:

1. La clase Builder:

public class MimeMessageBuilder {
    private MimeMessage message;

    public MimeMessageBuilder(Session session) {
        this.message = new MimeMessage(session);
    }

    public MimeMessageBuilder setFrom(String fromUser) throws MessagingException {
        this.message.setFrom(new InternetAddress(fromUser));
        return this;
    }

    public MimeMessageBuilder addReceivers(String... receivers) throws MessagingException {
        for (String receive : receivers) {
            this.message.addRecipient(Message.RecipientType.TO, new InternetAddress(receive));
        }
        return this;
    }

    public MimeMessageBuilder setSubject(String subject) throws MessagingException {
        this.message.setSubject(subject);
        return this;
    }

    public MimeMessageBuilder setTextContent(String content) throws MessagingException {
        this.message.setText(content, "utf-8");
        return this;
    }

    public MimeMessageBuilder setHtmlContent(String content) throws MessagingException {
        this.message.setContent(content, "text/html;charset=utf-8");
        return this;
    }

    public MimeMessage build() throws MessagingException {
        this.message.setSentDate(new Date());
        this.message.saveChanges();
        return this;
    }
}

public void sendTextMail(String title, String content, String... recives) {
        try {
            Properties props = new Properties();
            props.put("mail.smtp.ssl.enable", getMailConfig().getMailSmtpSslEnable());
            props.put("mail.smtp.host", getMailConfig().getMailSmtpHost());
            props.put("mail.smtp.auth", getMailConfig().getMailSmtpAuth());
            Session session = Session.getInstance(props);

            MimeMessage message = new MimeMessageBuilder(session)
                    .setFrom(getMailConfig().getSendUser())
                    .addReceivers(recives)
                    .setSubject(title)
                    .setTextContent(content)
                    .build();

            sendMail(message); // Delega la transmisión a un método separado
        } catch (MessagingException e) {
            LOGGER.error("Error construyendo el correo", e);
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions