Dúvida DAO - Design Patterns

Olá pessoal!

Sou novo por aqui e estou começando a desenvolver em Java.
Às vezes me pego perdendo muito tempo tentando entender os Design Patterns. Sou bastante perfeccionista e gostaria de seguir exatamente os conceitos. Só que não consigo sair do lugar pois sempre fico pensando se estou fazendo da forma correta.

A grande dúvida agora é com o Data Access Object.
Eu aprendi que, normalmente, é criado uma classe DAO para cada classe, como: ClienteDAO, ParceiroDAO, etc. Só que eu ouvi falar em DAO genérico e achei bastante interessante. Então, fiz uma interface de DAO genérica com métodos básicos do tipo: list, create, remove, update. E tenho uma classe Database. E uma interface DatabasePostgres. E, é claro, a classe model Cliente.

O problema agora é na hora de implementar tudo isso. O que devo fazer? Mesmo tento uma interface de DAO genérica, ainda preciso ter uma classe ClienteDAO que implementa esta interface, certo? Mas sendo assim, porque criar uma interface genérica? O que isso me traz de bom? E a classe Database? Ela deve ser uma subclasse de ClienteDAO ou ser uma instância?

Eu me perco nos conceitos, na forma como devo implementar cada um, a ordem, etc.

Por favor, vejam as classes abaixo. Estou usando os conceitos corretamente. Acho que a parte do banco não está ok. Não sei se devo criar uma interface para cada banco de dados e ainda por cima usar constantes. Isso me lembra muito linguagem procedimental. Posso estar falando besteira também …

  • Cliente.java
public class Cliente {
	private String name;
	private String email;
	private String login;
	private String senha;
	
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getLogin() {
		return login;
	}
	public void setLogin(String login) {
		this.login = login;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSenha() {
		return senha;
	}
	public void setSenha(String senha) {
		this.senha = senha;
	}
	public String toString(){
		
		StringBuffer res = new StringBuffer();
		res.append( "Nome: " + this.getName() + "\n" );
		res.append( "Email: " + this.getEmail() + "\n" );
		res.append( "Login: " + this.getLogin() + "\n" );
		res.append( "Senha: " + this.getSenha() );
		
		String rs = res.toString();
		return rs;
	}
}

DAO.java

public interface DAO<Object>{
	public void list();
	public Object create( Object o );
	public void remove( Object o );
	public void update( Object o );
}
  • ClienteDAO.java
public class ClienteDAO implements DAO{

	String tablename = "cliente";
	
	public Object create(Object object) {
		return object;
	}

	public void remove(Object object) {
		// TODO Auto-generated method stub
		
	}

	public void update(Object object) {
		// TODO Auto-generated method stub
		
	}

	public void list() {
		// TODO Auto-generated method stub
		
	}
}
  • Database.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Database implements DatabasePostgres{
	Connection con	= null;
	Statement stm	= null;
	ResultSet res	= null;
	
	public Connection getConnection(){
		if( con != null ){
			return con;
		}
		
		String url = JDBC_NAME + "://" + DB_HOST + "." + DB_PORT + "/" + DB_NAME;
		try {
			Class.forName( DRIVER_NAME );
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		try {
			con = DriverManager.getConnection( url, DB_USER, DB_PASS );
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return con;
	}
	
	public void closeConnection(){
		if( con != null ){
			try {
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	public ResultSet executeQuery( String sql ){
		Connection con = this.getConnection();
		
		try {
			stm = con.createStatement();
			res = stm.executeQuery( sql );
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		this.closeConnection();
		return res;
	}
}
  • DatabasePostgres.java
import java.sql.*;

public interface DatabasePostgres{
	static final String DB_HOST 	= "10.0.0.0";
	static final String DB_PORT 	= "5432";
	static final String DB_USER 	= "postgres";
	static final String DB_PASS 	= "postgres";
	static final String DB_NAME 	= "db_cliente";
	static final String JDBC_NAME	= "jdbc:postgresql";
	static final String DRIVER_NAME	= "org.postgresql.Driver";
	
	Connection getConnection() throws ClassNotFoundException, SQLException;
	void closeConnection() throws SQLException;
	ResultSet executeQuery( String sql ) throws SQLException;
}

Agradeço quem puder me ajudar! :slight_smile:

Obrigado!

oi ferinha…

Tens q. imaginar ‘interface’ como um contrato!
No momento q. vc cria uma interface estabele um contrato e todas as classes q. implementam essa interface são obrigadas a seguir esse contrato…ou seja…implementar os métodos definidos na interface…

Pense assim…vc está em uma equipe e possivelmente outra pessoa vá dar continuidade no seu código…se vc usa interface e as suas classes DAO implementam essa interface…o programador q. vai continuar terá q. necessariamente criar classes DAO q. implementam:

 public void list();
   public Object create( Object o );
   public void remove( Object o );
   public void update( Object o ); 

Espero ter ajudado! Não? Poste aí novamente.

t+

falae cara…vc esta tentando fazer as coisas de uma forma bacana…porem acredito q pelas suas duvidas, vc esta indo um pouco rapido, e deixando conceitos mais basicos para tras…por exemplo, Interface. Antes de falar de Patterns, seria interessante vc amadurecer mais na parte de Orientação a Objetos, pq depois entender os Patterns vai ficar bem mais facil…

eu me dou melhor olhando exemplos de projetos…normalmente algumas revistas publicam otimos exemplos…e tb ta cheio de tutoriais por aih…

a proposito, seu método list(), eh void…não deveria retornar uma List ??? :wink:

espero ter ajudado…

Olá Diana!
Obrigado pela ajuda com as interfaces. Eu já tinha isso um pouco claro na minha cabeça. :slight_smile:
O problema maior é quanto a outra dúvida sobre a classe Database e a interface DatabasePostgres. O conceito está correto? Devo usar a classe Database como instância dentro de ClienteDAO ou devo usá-la como subclasse de ClienteDAO?

pedrobusko,
Obrigado!
Também acho que deveria estar indo um pouco mais devagar, mas o trabalho me obriga a tomar esta atitude. Você deve entender o que estou falando. O tempo é muito curto e corrido demais.

E é verdade! O método list deve retornar um ArrayList mesmo. Passou batido! :slight_smile:

Geralmente eu tenho as mesmas duvidas… se estou usando os patterns da maneira realmente correta…

Sobre interfaces, eu achei diferente, pq eu sempre uso interfaces de maneira diferente…

Eu constuma criar um interface menos especifica, e um classe concreta implementando a interface mais espefica… usando seu exemplo eu criaria, uma interface Database e um classe concreta DatabaseOracle, implementando a interface Database…

No caso do DAO… eu criei um generico da seguinte maneira… do jeito que eu fiz, usando o eclipse fica um pouco mais rapido…

import java.sql.SQLException;
import java.util.List;

import bd.BD;
import beans.Entidade;

public abstract class GenericDAO<BEAN extends Entidade> {
	public abstract void save(BEAN bean,BD bd) throws SQLException;
	public abstract BEAN load(BEAN bean,BD bd) throws SQLException;
	public abstract List<BEAN> findAll(BD bd) throws SQLException;
	public abstract BEAN update(BEAN bean,BD bd) throws SQLException;
	public abstract void delete(BEAN bean,BD bd) throws SQLException;
}

Ai quando eu crio o DAO mais especifico ele e usando o eclipse para implementar os metodo abstratos ele ja faria o seguinte…

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import bd.BD;
import beans.Equipe;
import beans.Jogador;

public class JogadorDAO extends GenericDAO<Jogador>{

	@Override
	public void save(Jogador bean, BD bd) {
		
	}

	@Override
	public Jogador load(Jogador bean, BD bd) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Jogador> findAll(BD bd) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Jogador update(Jogador bean, BD bd) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void delete(Jogador bean, BD bd) {
		// TODO Auto-generated method stub
		
	}
}

No mais achei seu topico muito interessante… :lol: [/code]

Mas neste caso você está passando o objeto db como parâmetro em cada método. Isso seria a forma correta?

Alguém poderia nos esclarecer?

Ae, eu sempre usei algum framework de persistencia tipo hibernate, que geralmente possuem métodos que possibilitam vc criar uma classe genérica para inserir, atualizar, excluir, etc. Com sql e JDBC eu teria que pensar para ver como faria…

mas a questão de vc ter uma interface DAO, uma implementação abstrata dele (vamos supor com nome GenericDao) e depois ainda ter uma interface para um ‘ClienteDao’ por exemplo, é justamente para vc colocar em ClienteDao os métodos especializados do dao de cliente que não existe no GenericDao, como por exemplo buscaClientePeloNome, etc. Ai sua classe dao do cliente (ClienteDaoImpl) heradará de GenericDao e implementará ClienteDao.

Caso vc queira ver uma estrutura legal, da uma lida em (uma proposta de GenericDao utilizando o hibernate):
http://www.hibernate.org/328.html

Vc pode ter algumas idéias… mas é bom conversar com alguem que não usa um framework de persistencia para ver como fazer um GenericDao

valeu!