Inversão de Controle

3 respostas
ricardocomp

Olá pessoal,
eu estava fazendo o seguinte construtor
na minha classe TecnicoDao:

public class TecnicoDao {
    
    private Connection conn = null;
    private Statement stmt = null;
    
    //O.K.!!!
    public TecnicoDao() throws LAFQADaoException {
        try {
            this.conn = ConnectionFactory.getConnection();
        }
        catch (Exception e) {
            throw new LAFQADaoException("erro" + ":\n" + e.getMessage());
        }
    }
   
    public void salvarTecnico(Tecnico tecnico) throws LAFQADaoException {
       ...
       finally {
            try {
                ConnectionFactory.closeconnection(conn, ps);
            }
            catch (SQLException ex) {
                Logger.getLogger(TecnicoDao.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
   ...
}

Mas um amigo meu me falou que dessa maneira
eu poderia criar várias conexões então ele me indicou
fazer uma inversão de controle onde eu passaria a conexão
para o construtor.

Então fiz dessa maneira:

public class TecnicoDao{

    private Connection conn;

    //o.k.!!!
    public TecnicoDao(Connection conn) throws LAFQADaoException {
        try {
            this.conn = conn;
        }
        catch (Exception e) {
            throw new LAFQADaoException("erro" + ":\n" + e.getMessage());
        }
    }
...
}

e na hora de fazer o uso eu estou fazendo da seguinte forma:

Connection conn = ConnectionFactory.getConnection();
            produtorDAO = new ProdutorDao(conn);
            produtorDAO.salvarProdutor(produtor);
            conn.close();

Queria pedir uma opinião com vc’s sobre o que eu estou fazendo
se a inversão de controle é mesmo dessa forma?

[]'s.

3 Respostas

Java_Boy

Tem muitas pessoas mais experientes que dariam uma boa explicação, mas do que ja vi sobre IoC está correto sim, voce esta usando um dos tipos dela, no caso a famigerada Injeção de Dependência, e nela o tipo de Injeção de Dependência por Construtor

http://martinfowler.com/articles/injection.html#ConstructorInjectionWithPicocontainer

Mas, com certeza surgirão respostas e explicações melhores do assunto. Só aguardar =P

L

Sim, a inversão de Controle é desta forma.

Lembre-se que o objetivo principal é reduzir as dependências de uma determinada classe. No seu caso, antes seu DAO dependia de Connection e ConnectionFactory; agora depende apenas de Connection.

Porém, eu daria mais uma indireção. O seu conceito está certo, mas quando você recebe um Connection daquele jeito, nunca dá pra saber se é uma conexão aberta ou fechada. E se você passar um fechado por engano, dá pau. Com isso, eu não faria o ConnectionFactory como singleton, e o dividiria entre interface e implementação. Assim:

public interface ConnectionFactory {
    Connection getConnection();
}
public class DefaultConnectionFactory implements ConnectionFactory {
    public Connection getConnection() {
        // método para pegar conexão
    }
}

Aí seu DAO receberia a Factory (que teria a obrigação de entregar uma Connection em estado válido).

public class TecnicoDao {  
  
    private ConnectionFactory connFactory;  
  
    public TecnicoDao(ConnectionFactory connFactory) throws LAFQADaoException {  
        // é só uma atribuição
    	// não há necessidade de colocar num try/catch
    	this.connFactory = connFactory;  
    }  
...  
}

E a criação de objetos seria assim:

ConnectionFactory connFactory = new DefaultConectionFactory();
produtorDAO = new ProdutorDao(connFactory);  
produtorDAO.salvarProdutor(produtor);  
connFactory.close();

Ok?

ricardocomp

Olá A.L e Leonardo3001,
Obrigado pela ajuda, mas estou
com dificuldades em implementar
essa Injeção de Dependência, pois
a minha dúvida principal está no Dao

public class TecnicoDao {

     private Connection conn;  
   
     //o.k.!!!  
     public TecnicoDao(Connection conn){ 
            this.conn = conn;
     } 
       
        public void salvarTecnico(Tecnico tecnico) throws LAFQADaoException {
               //Como eu vou fechar o PreparedStatement agora???
               PreparedStatement ps = null;
               ...
          /* Antes eu fechava a conexão usando o bloco finally*/      
          finally {
            try {
                /* Fecha as Conexões e os PreparedStatement */
                ConnectionFactory.closeconnection(conn, ps);
            }
            catch (SQLException ex) {
                Logger.getLogger(TecnicoDao.class.getName()).log(Level.SEVERE, null, ex);
            }
          }
        }

Antes eu fechava a conexão usando o bloco Finally
e agora eu estou fechando as conexões da seguinte forma:

Connection conn = ConnectionFactory.getConnection();  
    produtorDAO = new ProdutorDao(conn);  
    produtorDAO.salvarProdutor(produtor);  
    //Fecha a conexão
    conn.close();

A minha dúvida é se eu tenho que retirar todo
o bloco Finally e o que eu devo fazer
para fechar o PreparedStatement corretamente?
Será que vc A.L, Leonardo3001 ou alguém pode
me dar uma ajuda?

[]'s.

Criado 7 de janeiro de 2010
Ultima resposta 7 de jan. de 2010
Respostas 3
Participantes 3