Explicar Design Pattern Singleton no VRaptor3

Olá pessoal,

Estou enrrolado com meu trabalho final, e estou com um probleminha em uma parte, estou falando sobre Design Patterns, e estou no Singleton atualmente, só que não estou conseguindo chegar em uma explicação de como o VRaptor aplica o Singleton quando anotamos uma classe com @SessionScoped ou @ApplicationScoped
Por que a base que eu to usando é o livro do GoF e lá explica um tipo de implementação, então queria saber se quando anotamos a classe o VRaptor por algum modo transforma essa classe nesse padrão…

Outra coisa que também gostaria de tirar uma duvida, é que pensei: se @SessionScoped e @ApplicationScoped são singletons, então com o VRaptor posso ter 2 niveis de singleton

Se eu estiver falando besteira, rs por favor me corrijam (rsrs mas sem mtas broncas pls rsrs)

Obrigado

Att.
Leonardo Lima

@SessionScoped definitivamente não é um singleton, pois vc tem várias instancias, um para cada sessão de usuários.

@SessionApplication vc pode considerar um singleton para o seu projeto, porem ele não segue o padrão, ele faz a instancia ser única, porem de outra forma, ele simplismente não instancia mais de uma pro seu projeto, porém qualquer pessoa pode instanciar o mesmo objeto sem chamar o component instanciado pelo vraptor.

O Singleton, faz com que vc garanta que apenas há uma instancia do objeto, pois ele torna o construtor privado, e quem instancia a classe é um método statico, e esse método statico garante uma só instancia.

Para criar um singleton com VRaptor vc teria que criar 2 classes, algo assim.

[code]public class MinhaClasseSingleton {
private static volatile MinhaClasseSingleton instance;
public static MinhaClasseSingleton getInstance() {
if (instance == null) {
synchronized(MinhaClasseSingleton.class) {
if (instance == null) instance = new MinhaClasseSingleton();
}
}
return instance;
}

 private MinhaClasseSingleton() {} //garante que só haverá uma instancia.

}

@Component
@ApplicationScoped
public SingletonCreator implements ComponentFactory<MinhaClasseSingleton> {
public MinhaClasseSingleton getInstance() {
return MinhaClasseSingleton.getInstance();
}
}[/code]

claro que ai vc não faz uso do poder do vraptor, que é a injeção de depencia, pois o singleton, é criado fora do Componente, mas desta forma há garantia que o MinhaClasseSingleton só exista uma vez no projeto, devido ao seu construtor privado.

os componentes @ApplicationScoped são singletons, se vc pensar que estamos usando Inversão de Controle: suas classes nunca instanciam outras classes, sempre recebem elas no construtor…

como o processo de instanciação é feito pelo VRaptor (na verdade o Spring), ele garante que tenha apenas uma instância, então é um singleton.

o que falam no GoF é uma implementação de singleton possível. Do mesmo modo que vc pode roubar e instanciar um componente AppScoped na mão, vc pode instanciar um Singleton statico via reflection.

[quote=Lucas Cavalcanti]os componentes @ApplicationScoped são singletons, se vc pensar que estamos usando Inversão de Controle: suas classes nunca instanciam outras classes, sempre recebem elas no construtor…

como o processo de instanciação é feito pelo VRaptor (na verdade o Spring), ele garante que tenha apenas uma instância, então é um singleton.

o que falam no GoF é uma implementação de singleton possível. Do mesmo modo que vc pode roubar e instanciar um componente AppScoped na mão, vc pode instanciar um Singleton statico via reflection.[/quote]

é … é verdade, como disse, ele é singleton para o vraptor, e realmente da pra instanciar um singleton via reflections tb =x

vixiii esse lucas é um monster do conhecimento kkk
pior que eu fico boiando de como eu vou escrever isso kkk

O texto que tenho pronto até agora é esse:

Agora eu precisaria fazer a junção para mostrar como é usado esse padrão no VRaptor rs

Outra duvida que eu to é sobre o Facade, geralmente eu uso mto no C# Helper, e eu andei analisando acho q o que eu chamo de Helper na verdade é um Facede, alguem poderia confirmar se é msmo ?

Vou mandar aqui em baixo uma classe que to usando para enviar email, estou errado em dizer que está classe é um Facade ?

package br.com.evto.util;

import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

public class SendMail {

    private String mailSMTPServer;
    private String mailSMTPServerPort;
    private String mailUsername;
    private String mailPassword;

    /*
     * quando instanciar um Objeto ja sera atribuido o servidor SMTP do GMAIL
     * e a porta usada por ele
     */
    public SendMail() { //Para o GMAIL
        mailSMTPServer = "smtp.gmail.com";
        mailSMTPServerPort = "465";
        mailUsername = "*****";
        mailPassword = "****";
    }
    /*
     * caso queira mudar o servidor e a porta, so enviar para o contrutor
     * os valor como string
     */

    SendMail(String mailSMTPServer, String mailSMTPServerPort) { //Para outro Servidor
        this.mailSMTPServer = mailSMTPServer;
        this.mailSMTPServerPort = mailSMTPServerPort;
    }

    public void sendMail(String from, String to, String subject, String message) {

        Properties props = new Properties();

        //CONFIG PARA SERVIDOR PROXY
        //props.setProperty("proxySet","true");
        //props.setProperty("socksProxyHost","192.168.155.1"); // IP do Servidor Proxy
        //props.setProperty("socksProxyPort","1080");  // Porta do servidor Proxy

        props.put("mail.transport.protocol", "smtp"); //define protocolo de envio como SMTP
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", mailSMTPServer); //server SMTP do GMAIL
        props.put("mail.smtp.auth", "true"); //ativa autenticacao
        props.put("mail.smtp.user", from); //usuario ou seja, a conta que esta enviando o email (tem que ser do GMAIL)
        props.put("mail.debug", "true");
        props.put("mail.smtp.port", mailSMTPServerPort); //porta
        props.put("mail.smtp.socketFactory.port", mailSMTPServerPort); //mesma porta para o socket
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");

        //Cria um autenticador que sera usado a seguir
        SimpleAuth auth = null;
        auth = new SimpleAuth(mailUsername, mailPassword);

        //Session - objeto que ira realizar a conexão com o servidor
		/*Como há necessidade de autenticação é criada uma autenticacao que
         * é responsavel por solicitar e retornar o usuário e senha para
         * autenticação */
        Session session = Session.getDefaultInstance(props, auth);
        session.setDebug(true); //Habilita o LOG das ações executadas durante o envio do email

        //Objeto que contém a mensagem
        Message msg = new MimeMessage(session);

        try {
            //Setando o destinatário
            msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
            //Setando a origem do email
            msg.setFrom(new InternetAddress(from));
            //Setando o assunto
            msg.setSubject(subject);
            //Setando o conteúdo/corpo do email
            msg.setContent(message, "text/plain");

        } catch (Exception e) {
            System.out.println(">> Erro: Completar Mensagem");
            e.printStackTrace();
        }

        //Objeto encarregado de enviar os dados para o email
        Transport tr;
        try {
            tr = session.getTransport("smtp"); //define smtp para transporte
			/*
             *  1 - define o servidor smtp
             *  2 - seu nome de usuario do gmail
             *  3 - sua senha do gmail
             */
            tr.connect(mailSMTPServer, mailUsername, mailPassword);
            msg.saveChanges(); // don't forget this
            //envio da mensagem
            tr.sendMessage(msg, msg.getAllRecipients());
            tr.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.out.println(">> Erro: Envio Mensagem");
            e.printStackTrace();
        }

    }
}

//clase que retorna uma autenticacao para ser enviada e verificada pelo servidor smtp
class SimpleAuth extends Authenticator {

    public String username = null;
    public String password = null;

    public SimpleAuth(String user, String pwd) {
        username = user;
        password = pwd;
    }

    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(username, password);
    }
}

como não é vc que instancia as classes, então todos os construtores são invisíveis :wink: Pra sua classe tanto faz qual é o construtor da classe (ou da implementação de uma interface) recebida no construtor.

é que o conceito é outro: escopo. O escopo do objeto é Singleton. E a gente usa escopos qdo está trabalhando com Injeção de dependências (que tb é um design pattern)

e sim, sua classe é um façade, pois melhora a interface de enviar emails

Lucas… Lavieri…

Poderiam dar uma opnião sobre o que eu escrevi, e se caso eu escrevi algo errado ou alguma besteira, poderiam ajudar na correção???

olá Leonardo,

em java a gente tem Injeção por Construtor, Setter e Field, que vc não pôs aí… o Field seria settar o field diretamente por reflection

onde vc leu Interface Injection?

e evita usar termos em inglês quando existe tradução equivalente, se isso é um trabalho de faculdade…

opa cara…
essa do Interface Injection li neste post: http://javafree.uol.com.br/artigo/871453/#ANaiveExample

Valeu pela dica dos termos em ingles, vou traduzi-los rsrs

Ahh sobre este modo de Injeção, que seria o Field, tem algum material para me indicar para eu ler, pq sinceramente nunca vi…

se vc procurar no Spring, ou EJB… eles tem suporte a field injection. Basicamente vc anota um field e eles magicamente (por reflection) injetam o que vc pediu

esse interface injection é a mesma coisa que setter injection, só que os nomes dos métodos são diferentes, e vc é obrigado a criar uma interface só pra isso…

qse nenhum framework faz isso, é bem feio… o Spring faz algo parecido, mas usa setters pra injeções: p.e a interface BeanFactoryAware

ohhhh dureza…
explicar essas magicas que é o complicado…
bom vou no BonOdori aqui de Jales, distrair a cabeça um pouco kkk (pra melhorar o dia… levei uma multa tosca!! ) rsrs

tirando essa parte dos termos em ingles e faltando esse field injection o restante tá bom né ?

Mais uma vez!
OBRIGADOOOO :slight_smile:

não sei, depende do seu professor :wink: mas parece bom =)
boa sorte ai!

Grande lucas!!

Pode me ajudar a explicar de forma resumida a Interface Injection ?
Sei que tu explicou ali em cima, mas não consegui entender…
To usando como referencia http://martinfowler.com/articles/injection.html

E lá o cara cita esse modo… mas não consegui bolar uma forma resumida para escrever sem precisa explicar aquele caminhão de coisa, rsrs pq acho q preciso só falar que existe e oq é por cima né ?

o que fiz ate agora ficou assim:

? Injeção por Interface (Interface Injection): Esta técnica resume-se em definir interfaces e utilizá-las para injetar as dependências. Uma classe dependente deve implementar a interface de sua dependência.