Mais uma duvida sobre DAO

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

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

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

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:

Qual o embasamento dele?

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???

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 ); }

[code]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 ) { … }
}[/code]

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á!

[quote=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á![/quote]

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

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

[quote=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á![/quote]

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.

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.

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.

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

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.

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.

é 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:

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

é 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[/quote]

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.

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());

	}
}

[quote=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.[/quote]

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