Aplicando padrões de projeto

Boa noite! Estou desenvolvendo um trabalho de faculdade aonde temos que implementar 3 padrões de projeto de nossa preferência em algum projeto em java existente ou então começar um do zero…para poupar tempo eu quero utilizar um projeto em java p web e hibernate que é de outra matéria…estou meio confusa…conheço alguns dos principais padrões, implementamos alguns exemplos em aula, mas não estou 100% segura para aplicar eles sozinha agora…apesar de ler e ver mais exemplos ainda preciso de ajuda…

Então minha primeira dúvida:

Tenho a classe HibernateUtil a seguir

package util;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 *
 * @author SONY
 */
public class HibernateUtil {
    private static EntityManagerFactory factory =null;

    public static EntityManager getManager(){
        try{
        if (factory == null){
            factory = Persistence.createEntityManagerFactory("ContasPU");
        }
        return factory.createEntityManager();

    } catch(Exception e){
            System.out.println("Erro"+e);
            return null;
    }

}
}

Toda vez que é necessário seu uso chamo ela nos arquivos.jsp

                    EntityManager manager = HibernateUtil.getManager();

e a definição do PP Singleton: estabelece a regra de que só pode existir um objeto disponível na memória para a classe que implementa este padrão.
A minha classe HibernateUtil já é um exemplo de Singleton então? Se não, como fazer para que seja?

Obrigada!! :smiley:

Olá,

Para fazer um teste rapido se sua classe é Singleton é facil. Tente fazer duas vezes new() dela, se voce conseguir ela nâo é Singleton :slight_smile:

Abraços
Daniel

consegui :evil: pela primeira vez, gostaria de não ter conseguido…ahahahahah…
ironias a parte, o que na minha classe vai determinar que se trata de um Singleton?

e agora:


package util;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 *
 * @author SONY
 */
public class HibernateUtil {

    private static final HibernateUtil hibernate = new HibernateUtil();
    private static EntityManagerFactory factory = null;

    private HibernateUtil() {
    }

    // retorna o objeto Singleton estático
    public static HibernateUtil getInstance() {
        return hibernate;
    }

    public static EntityManager getManager() {
        try {
            if (factory == null) {
                factory = Persistence.createEntityManagerFactory("ContasPU");
            }
            return factory.createEntityManager();

        } catch (Exception e) {
            System.out.println("Erro" + e);
            return null;
        }

    }
}

??

Pelo menos acusou um erro (nunca pensei que ia ficar feliz com isso)…tentei criar um novo objeto

HibernateUtil util = new HibernateUtil(); e acusa que o HibernateUtil é de acesso privado…é isso?? :roll:
Pq eu criei um construtor privado, óbvio…o que impede a instanciação…então agora eu tenho um singleton?

Pergunta do primeiro post:

Não. A EntityManagerFactory é um singleton, pois é criada somente uma vez e acessada para criar entidades depois de instanciada. A HibernateUtil é somente uma classe de acesso. Se for seguir o padrão à risca haveria um método chamado getInstance() na EntityManagerFactory que retornaria sempre a mesma instância do objeto, mas isso não impede que seja feito da forma que você fez.

[quote]Pelo menos acusou um erro (nunca pensei que ia ficar feliz com isso)…tentei criar um novo objeto
view plaincopy to clipboardprint?
HibernateUtil util = new HibernateUtil();
e acusa que o HibernateUtil é de acesso privado…é isso??
Pq eu criei um construtor privado, óbvio…o que impede a instanciação…então agora eu tenho um singleton?[/quote]

Agora sim :slight_smile:

Veja que voce tem um objeto HibernateUtil já instanciado dentro da sua propria classe e ninguem de fora consegue fazer um new() dessa sua classe, ou seja o
construtor private é essencial para se ter um Singleton.

É isso ai

Abraços
Daniel.

e agora to fazendo certo??

[code]package util;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
*

  • @author SONY
    */
    public class HibernateUtil {

    // Objeto Singleton a ser retornado por getSingletonInstanc
    private static EntityManagerFactory factory = null;

    // construtor privado impede a instanciação pelos clientes
    private HibernateUtil() {
    }

    // retorna o objeto Singleton estático
    public static EntityManager getInstance() {
    try {
    if (factory == null) {
    factory = Persistence.createEntityManagerFactory(“ContasPU”);
    }
    return factory.createEntityManager();

     } catch (Exception e) {
         System.out.println("Erro" + e);
         return null;
     }
    

    }
    }
    [/code]

e chamo assim em todas as paginas necessárias

EntityManager manager = HibernateUtil.getInstance();

[quote]Agora sim

Veja que voce tem um objeto HibernateUtil já instanciado dentro da sua propria classe e ninguem de fora consegue fazer um new() dessa sua classe, ou seja o
construtor private é essencial para se ter um Singleton.

É isso ai

Abraços
Daniel.[/quote]

Eba! Obrigada!!

Alguma sugestão sobre que outro padrão eu poderia usar em um projeto de um sistema de gerenciamento de contas a pagar e receber super simples em JSP, Hibernate e o banco de dados Postgres?

Funcionalidades do sistema:
? Inserir conta
? Editar conta
? Remover conta
? Listagem

Um Excelente pro seu caso, o Padrão Command.

Abraços
Daniel.

huumm…vou pesquisar…aproveitando que tu ta online, eu quero testar de alguma maneira o exemplo usando o singleton…mas não to sabendo muito cm…to querendo algo assim assim:

 //construtor
 private HibernateUtil() {
         System.out.println("Factory sendo utilizada...");
    }

//....
//e na pagina jsp pensei em algo algo assim...

HibernateUtil firstHibernateUtil;
    HibernateUtil secondHibernateUtil;
    firstHibernateUtil = HibernateUtil.getInstance();
    secondHibernateUtil = HibernateUtil.getInstance();

    if (firstHibernateUtil == secondHibernateUtil) {
%>
        <%="FirsHibernateUtil e secondHibernateUtil fazem referência ao mesmo HibernateUtil");%>

<%            }

tem fundamento isso? este código ta dentro da pagina inserir.jsp…só pra fazer um teste…

No seu último exemplo da classe HibernateUtil… ela é um singleton MAS sem utilidade nenhuma… então não tem razão para usar esse padrão. Você nao está usando nenhuma instancia do objeto HibernateUtil.

A EntityManagerFactory NÃO é um singleton!

Olá,

Aproveitando que eu estou online e vou responder rsrs…

Sim esse é um bom teste para ver a questão do singleton, exatamente voce pode recuperar a instancia varias vezes, por variaveis diferentes e ver se todas apontam para o mesmo objeto, se sim ok! Singleton implementado :slight_smile:

Dicas : Evite sempre usar scriptlets em paginas jsp isso é uma má prática, a ideia de uma pagina jsp é de somente representar a interface grafica, no caso a pagina, deixe a codificações para um objeto que se comunique diretamente com suas paginas .jsp’s que no caso são os controllers(Servlets).

Qualquer dúvida é só falar.

Abraços
Daniel.

Para transformar o seu HibernateUtil em um singleton que faça algum sentido, troque o método [color=darkred]public static EntityManager getInstance()[/color] por um método não estático e o renomeie para getEntityManager().

Crie outro [color=darkred]getInstance[/color] que retorna a instancia de HibernateUtil.

[quote]No seu último exemplo da classe HibernateUtil… ela é um singleton MAS sem utilidade nenhuma… então não tem razão para usar esse padrão. Você nao está usando nenhuma instancia do objeto HibernateUtil.

A EntityManagerFactory NÃO é um singleton! [/quote]

Poi é!! Eu quero que seja útil…cm eu faço isso?

Exatamente o que ele disse, tinha esquecido disso rsrs

Utilize o padrão Singleton para encapsular algo, pois não adianta ter uma classe singleton que não forneça nenhuma funcionalidade específica.

Abraços
Daniel

Instruções acima… fazendo essas modificações ao pedir um EntityManager automaticamente você terá que usar o singleton do HibernateUtil.

Dica, o que será estático na sua classe será:
Um atributo do tipo [color=darkred]HibernateUtil[/color]
e o método [color=darkred]public static HibernateUtil getInstance()[/color]

Você terá algo mais ou menos assim na sua classe:

private static HibernateUtil instance;

public static HibernateUtil getInstance(){
     // código para retornar o singleton aqui
}

private HibernateUtil(){ //o construtor de HibernateUtil deve ser private
}

//outros métodos públicos e não estáticos

[code]package util;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**

  • Padrão de projeto aplicado:

  • Singleton: Singleton: estabelece a regra de que só pode existir um objeto disponível

  • na memória para a classe que implementa este padrão.

  • Temos um objeto HibernateUtil já instanciado dentro da própria classe e

  • ninguem de fora consegue fazer um new() dessa classe, ou seja o

  • construtor private é essencial para se ter um Singleton, pois impede a instanciação da classe.
    */
    public final class HibernateUtil {

    // Objeto HibernateUtil a ser retornado por getInstance
    private static final HibernateUtil hibernate = new HibernateUtil();
    private static EntityManagerFactory factory = null;

    // construtor privado impede a instanciação pelos clientes
    private HibernateUtil() {
    System.out.println(“Factory sendo utilizada…”);
    }

    // retorna o objeto HibernateUtil estático
    public static HibernateUtil getInstance() {
    return hibernate;
    }

    public static EntityManager getManager() {
    try {
    if (factory == null) {
    factory = Persistence.createEntityManagerFactory(“ContasPU”);
    }
    return factory.createEntityManager();

     } catch (Exception e) {
         System.out.println("Erro" + e);
         return null;
     }
    

    }
    }
    [/code]

O método getManager() deve ser não estático…

Segue como fica :

[code]package com.patterns.singleton;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**

  • Padrão de projeto aplicado:

  • Singleton: Singleton: estabelece a regra de que só pode existir um objeto disponível

  • na memória para a classe que implementa este padrão.

  • Temos um objeto HibernateUtil já instanciado dentro da própria classe e

  • ninguem de fora consegue fazer um new() dessa classe, ou seja o

  • construtor private é essencial para se ter um Singleton, pois impede a instanciação da classe.
    */
    public final class HibernateUtil {

    // Objeto HibernateUtil a ser retornado por getInstance
    private static final HibernateUtil hibernate = new HibernateUtil();
    private static EntityManagerFactory factory = null;

    // construtor privado impede a instanciação pelos clientes
    private HibernateUtil() {
    System.out.println(“Factory sendo utilizada…”);
    }

    // retorna o objeto HibernateUtil estático
    public static HibernateUtil getInstance() {
    return hibernate;
    }

    public EntityManager getEntityManager() {
    try {
    if (factory == null) {
    factory = Persistence.createEntityManagerFactory(“ContasPU”);
    }
    return factory.createEntityManager();
    } catch (Exception e) {
    System.out.println(“Erro” + e);
    return null;
    }
    }
    }
    [/code]

Exemplo de uso :

import javax.persistence.EntityManager;

public class Main {
	
	public static void main(String[] args) {
		
		HibernateUtil util1 = HibernateUtil.getInstance();
		HibernateUtil util2 = HibernateUtil.getInstance();
		
		//comparando referencias...
		if(util1 == util2){
			System.out.println(true);
		}else{
			System.out.println(false);
		}
		
		// obtendo entity manager
		EntityManager em1 = HibernateUtil.getInstance().getEntityManager();

	}

}

Daniel! Aproveitando que tu ta online foi ótima né?? ahahaha Vou ler as dicas com atenção … não me abandonem!