Mais uma duvida sobre DAO

30 respostas
AntonioMafiotecano

Fala galera, estou aqui de novo precisando do conhecimento de vcs rs. Acontece o seguinte estamos criando classes DAO para o nosso projeto mas entramos num impasse(escrevi certo?) com um outro programador aqui sobre os metodos de acesso ele diz que esses metodos tem q ser staticos. Estaria ele certo?

Para ilustrar qual dos exemplos abaixo é o correto?

Bean utilizado pelas duas classes DAO

Classe DAO com metodos não estaticos(nesse caso toda vez q for inserir um bean no banco terei de instanciar uma classe DAO)

Classe DAO com metodos estaticos, nesse caso não sera necessario instanciar uma classe DAO apenas para inserir um bean no banco.

Entao galera alguem sabe me dizer qual a maneira correta segundo as espeficicações do DAO?Valeu

30 Respostas

Leozin

eu não acho legal fazer estático porque você terá que fazer ele ser synchronized (se houver grande número de acessos ao DAO) e, sendo synchronized, além de poder acessas o método somente um usuário (thread) por vez, ele diminui drasticamente o desempenho

faça um bean normal, faça a instância somente na hora que for usar que não haverá esse problema hehe (mas vai comer mais memória do servidor, pode ter certeza) :slight_smile:

bom é o que eu acho

AntonioMafiotecano

Opa valeu. Eu tb prefiro metodos nao staticos, mas o outro programador acha examente o contrario.

drix

Concordo com o Leozin.

Mas para resolver o impasse… rsrss.
Faça os testes:

  • Monte um DAO com métodos estáticos e outro com não estáticos;
  • Faça os testes de tempo, e verá que o desempenho realmente cae, compartilhando a mesma classe para múltiplos acessos.

Relato que, tb passe por esta dúvida e estes testes foram decisivos para obter a melhor solução. :wink:

danieldestro

Qual o embasamento dele?

AntonioMafiotecano

Ele diz que é desnecessario criar uma instancia apenas para inserir um dado, que o metodo seria naturalmente estatico.
Mas me surgiu uma duvida agora… se eu fizer o DAO com metodo nao estatico e nao sincronizados, como irei impedir q se tente inserir ao mesmo tempo???

danieldestro

Com métodos estáticos você terá problemas se usa recursos compartilhados.

Agora, vou provar como seu amigo perde a razão. Num sistema onde você usa um mecanismo mais, digamos, complexo de DAOs e você quer se aproveitar da OO e das possibilidades que o Java te dá, usar métodos estáticos não dá muito certo.

Exemplo:

public interface DAO {
  public void insert( Object o );
  public void delete( Object o );
  public void update( Object o );
}
public abstract class JdbcDAO implements DAO {
  public Connection getConnection() {
    //pega a conexão e retorna
  }
}
public class PessoaDAO extends DAO {
  public Pessoa buscar( Integer id );
}
public class PessoaJdbcDAO extends JdbcDAO implements PessoaDAO {
  public void insert( Object o ) {
    conn = getConnection();
    sql = "INSERT ....";
    //faz o resto
  }

  public void delete( Object o ) { ... }
  public void update( Object o ) { ... }
  public Pessoa buscar( Integer id ) { ... }
}
public class DAOFactory {
  public static DAO getDAO( Class clazz ) {
     //cria o DAO pela classe informada e retorna
  }
}

Como usar o mecanismo:

PessoaDAO dao = (PessoaDAO) DAOFactory.getDAO( PessoaDAO.class );
dao.buscar( id );

Agora, pergunta pro seu amigo se ele faz isso com métodos estáticos de uma maneira elegante?!?!?!?!

Com este mecanismo fica MUITO fácil trocar de JDBC pra Hibernate ou qq outra implementação que você faça, até mesmo híbrido, como eu uso aqui, já que é tudo baseado nas interfaces. Aí é só fazer um mecanismo de configurações e voilá!

AntonioMafiotecano

danieldestro:
Com métodos estáticos você terá problemas se usa recursos compartilhados.

Agora, vou provar como seu amigo perde a razão. Num sistema onde você usa um mecanismo mais, digamos, complexo de DAOs e você quer se aproveitar da OO e das possibilidades que o Java te dá, usar métodos estáticos não dá muito certo.

Agora, pergunta pro seu amigo se ele faz isso com métodos estáticos de uma maneira elegante?!?!?!?!

Com este mecanismo fica MUITO fácil trocar de JDBC pra Hibernate ou qq outra implementação que você faça, até mesmo híbrido, como eu uso aqui, já que é tudo baseado nas interfaces. Aí é só fazer um mecanismo de configurações e voilá!

Eu concordo contigo, valeu pela ajuda. Estou no forum a menos de uma semana e já fui muito ajudado por vcs. Realmente essa comunidade merece a fama que tem :lol: :lol: :lol: valeu

louds

Métodos estáticos devem ser evitados a todo custo. Eles criam mais problemas do que resolvem.

Edufa

danieldestro:

Com este mecanismo fica MUITO fácil trocar de JDBC pra Hibernate ou qq outra implementação que você faça, até mesmo híbrido, como eu uso aqui, já que é tudo baseado nas interfaces. Aí é só fazer um mecanismo de configurações e voilá!

Eu uso essa mesma abordagem, mas gostaria de saber como vc faz para fazer esta parte híbrida JDBC + Hibernate. Como não posso mexer no banco e resolvi fazer o modelo de classes mais voltado a OO, acabei ficando com alguns pepinos para fazer a parte hibernate, então uma abordagem híbrida seria o ideal para mim, qq sugestão é bem vinda.

danieldestro

Assim como eu tenho PessoaJdbcDAO, eu posso ter PessoaHibernateDAO. Mas é um OU outro. Mesmo assim você pode misturar os dois ali dentro de uma implementação, sem problemas.

Edufa

Sim até aí tranquilo.
Mas o seu factory ou cria objetos JDBCDao ou HibernateDao, por isso e é por isso q é fácil mudar entre um e outro é só mudar a factory.
No meu caso eu queria q qdo eu chamasse determinados métodos ele usasse outra factory, qual a melhor maneira de fazer isso, se é viável, ou estou complicado e deveria fazer na mão mesmo.

DAOFactory daoFactory = HibernateDAOFactory();
// Aqui ele pegaria Hibernate factory
CategoriaDAO daoCategoria = (CategoriaDAO) daoFactory.getDAO( CategoriaDAO.class );
daoCategoria.buscar( id );

// Aqui pegaria JDBC factory
PessoaDAO dao = (PessoaDAO) daoFactory.getDAO( PessoaDAO.class );
daoPessoa.buscar( id );

O motivo para essa complicação, é q eu gostaria q no código mesmo ficasse transparente qual a DAO factory q está sendo usada e em algum lugar eu definiria isso. Depois se eu conseguisse reproduzir com hibernate a mesma performance dos casos mais complexos eu mudaria as configurações e não precisaria mexer no resto.

danieldestro

Se você faz isso, você está amarrando seu negócio com o tipo específico de implementação de DAO. A solução que mostrei justamente desacopla.

No meu caso eu tenho só um DAOFactory. Ele lê de um arquivo qual classe concreta eu uso para cada interface DAO.

Ex:

meu.dao.PessoaDAO=meu.dao.jdbc=PessoaJdbcDAO
meu.dao.XyzDAO=meu.dao.hibernate.XyzHibernateDAO

Edufa

Humm, entendi, eu interpretei como se vc tivesse vários DAOFactory um para cada forma de persistencia. Você concentra tudo num único DAOFactory q le esses parâmetros e assim ele sabe qual DAO usar (Hibernate ou JDBC, ou etc), é bem isso que eu precisava, estava quebrando a cabeça, … Valeu.

pcalcado

Ok, métodos estáticos não são a melhor opção porque acabam afetando a estrutura OO do sistema. Metodos estáticos não são métodos soltos no espaço, são métodos que pertencem à classe, não ao objeto.

mAs… o que tem a ver o snchronized? Estático ou não, você teria o mesmo problema.

Leozin

é que se eles estão no seguine dilema:

Utilizar um DAO estático ou não

Se há DAO estático, não haverá instância, terá somente o ClasseDAO.getXXX(), se não for estático, a classe DAO somente será instanciada quando houver um CRUD, ou seja, não sendo estático, não haverá problemas se, digamos, 1000 pessoas estiverem usando EXATAMENTE o mesmo método (pois a praga é estática) :stuck_out_tongue:

furutani

E se os DAO´s forem sigletons seria um tiro no pé?

louds

é que se eles estão no seguine dilema:

Utilizar um DAO estático ou não

Se há DAO estático, não haverá instância, terá somente o ClasseDAO.getXXX(), se não for estático, a classe DAO somente será instanciada quando houver um CRUD, ou seja, não sendo estático, não haverá problemas se, digamos, 1000 pessoas estiverem usando EXATAMENTE o mesmo método (pois a praga é estática) :P

E qual o problema de mil pessoas chamarem o mesmo método, do mesmo objeto, ao mesmo tempo? Nenhum se a classe for projetada para isso, que quase sempre é o caso para DAOs.

rodrigoy

Na minha aula de OO, muitos programadores ficam espantados quando digo que um atributo estático é compartilhado entre todas as instâncias e se você mexer nele todas as instâncias são impactadas. Muitos acham que atributo static é só para criar constantes. Tenho um exemplinho:

public class Order {
	private static long nextOrderNumber = 0;
	private long orderNumber = 0;
	private String customerName;
	
	public Order (String customerName) {
		this.customerName = customerName;
	}
	
	
	public void save() {
		/*zero = novo pedido*/
		if (orderNumber == 0) orderNumber = nextOrderNumber++;
		System.out.println("Pedido #" + this.orderNumber + " para " + this.customerName + " sendo salvo!");
	}

	public static long getNextOrderNumber() {
		return nextOrderNumber;
	}
	
	public static void main(String[] args) {
		
		new Order("Joao").save();
		new Order("Pereira").save();
		System.out.println("O próximo pedido será = " + Order.getNextOrderNumber());

	}
}
brunohansen

pcalcado:
Ok, métodos estáticos não são a melhor opção porque acabam afetando a estrutura OO do sistema. Metodos estáticos não são métodos soltos no espaço, são métodos que pertencem à classe, não ao objeto.

mAs… o que tem a ver o snchronized? Estático ou não, você teria o mesmo problema.

Muito boa pergunta!!! Problemas de concorrencia vc tem tanto em métodos estaticos quando em métodos de objetos instanciados e compartilhado por referencia.

Fabricio_Cozer_Marti

pcalcado:

mAs… o que tem a ver o snchronized? Estático ou não, você teria o mesmo problema.

também acho, não é porque os métodos ou atributos são estáticos que você vai ter problemas de concorrência.

O problema de concorrência independe da estaticidade deles.

Sobre usar ou não, prefiro usar somente para constantes, para métodos de classes utilitárias, e para realmente compartilhar dados em um objeto que seja singleton, de resto ignore a utilização sempre.

Sobre DAO, ainda vejo um armengue para adapatar linguagens O.O. com bancos relacionais. :cry:

Luiz_Gustavo

se me permite uma observação :smiley:

aqui seria uma interface, não?!

public interface PessoaDAO extends DAO{}…

[]'s

AntonioMafiotecano

Bom galera obrigado pela ajuda, consegui argumentos suficientes para defender minha preferencia pelo modelo não estático, e já convenci o programador a fazer assim tb, obrigado.

A

Fabrício Cozer Martins:
pcalcado:

mAs… o que tem a ver o snchronized? Estático ou não, você teria o mesmo problema.

também acho, não é porque os métodos ou atributos são estáticos que você vai ter problemas de concorrência.

O problema de concorrência independe da estaticidade deles.

Masomeno. Se uma instância nunca escapar da thread então você não precisaria se preocupar com acessos concorrentes em métodos de instância mas com os métodos estáticos não tem como ter essa garantia. No caso de DAOs isso não importaria porquê é fácil escrever os métodos para funcionar concorrentemente (sem synchronized…). Mas dizer que em geral “O problema de concorrência independe da estaticidade” não é verdade.

paulohbmetal

Ressucitando o tópico… Mas calma aí, se eu criar um DAO a cada requisição no servidor estarei ferrado não?! :?

Pois para cada consulta que fizer, estarei requisitando ao Factory uma instancia e por causa de um método do DAO.

Vc’s fazem isso para as classes de negócio também?!

A Paz!!

mutano

No caso de DAOs que não tem estado, apenas comportamento, também não faria sentido usar static?

paulohbmetal

Alguém?!

A Paz!!

Thiago_Senna

Se quando terminar a lógica de negócio o seu dao estiver disponível para coleta de lixo, e se o seu DAO for peso leve para ser instanciado, não vejo problemas.

louds

Também não. Métodos estáticos castram por completo você usar recursos OO.

paulohbmetal

O que vc quis dizer com peso leve?

Pergunto isso pois acho disperdício de memória e também pq estou desenvolvendo uma aplicação RMI e tenho que preocupar com tudo isso, inclusive para as classes de negócio. :frowning:

A Paz!!

Thiago_Senna

eu chamo de peso leve objetos que não são pesados de ser instanciados.

Se seu DAO for simples e não fica carregando um monte de recursos durante a instanciação, não vejo problemas em instanciá-lo cada vez que precisar dele.

Criado 29 de junho de 2006
Ultima resposta 10 de ago. de 2006
Respostas 30
Participantes 16