Duvida POO

Pessoal,

Estou lendo a apostila da caelum fj21 e estou com a seguinte duvida de conceito…

Imagine que vou criar um classe contato (nome, fone e endereço) e vou gravar em um BD.

Então crio a classe contato (para fazer o bean )

e uma classe ContatoDAO para fazer os acessos no banco.

se eu crir um metodo salva que recebe o contato por paramentro [ salvaContato(Contato contato) ] no meu ponto de vista isso não fica legal… pois não acho que deva ser certo passar o contato por paramentro… e também desta forma perde o sentido de ter uma instancia de ContatoDAO… o metodo salva poderia ser static e se fizer assim meu programa vai ter muito mais cara de um programa com funções…rs

Por outro lado se a Classe ContatoDAO extender a contato… eu posso ter um metodo salvaContato() e ele já vai ser capaz de fazer tudo ok!!! e bem POO na minha visão… só que ai caio em outro problema… a minha Classe num vai acabar sendo responsavel por mais coisas do que ela realmente deveria ser ??? e isso vai ficar errado nos conceitos de POO???

Alguém tem alguma dica de como poderia resolver este problema de forma que fique de acordo com a POO ?

Obrigado,

Marcelo Gomes

Na verdade cara… o acesso ao banco é feito por uma classe que pode ser denominada (e geralmente é) de ConnectionManager. Lá, você obtém a conexão com o banco e etc.

O que acontece com o DAO é a vantagem de se ter uma interface onde se pode definir métodos de persistência nos dados que são comuns para todas as classes do seu sistema. Exemplo: save, update, delete, etc…

E quando você vai programar Orientado a Objetos, vc tem que pensar orientado à objetos. Ou seja, você não tem que pensar que vc está gravando um registro em uma tupla de uma tabela de um banco de dados. Você tem que pensar que você está gravando um OBJETO dentro de uma tabela do banco de dados. Por isso que a abordagem de que o método salvaContato() tem que receber um objeto do tipo Contato como parâmetro é totalmente correta e dentro dos padrões da POO.

Como vc deve ter percebido, a classe DAO é uma INTERFACE e os “beans” de cada uma das classes que mapeiam entidades da sua base de dados devem implementá-la.

Ou seja, vc vai ter a classe Contato (que representa sua entidade do banco de dados), a classe ContatoDB (o seu bean, que implementa DAO e define como os métodos da interface serão utilizados) e a Interface ContatoDAO, que vai conter a especificação dos métodos comuns para todos os beans.

Quando vc quiser salvar um objeto na base de dados, vc setará os atributos da classe Contato e acessará o método save(Contato contato) que está dentro da sua Classe ContatoDB…

ContatoDAO dao = new ContatoDB();

aqui, você armazena no heap do java, uma variável do tipo ContatoDAO, que possui os métodos contidos na interface, porém, a execução dos mesmos, é feita dentro da classe ContatoDB, pois ela implementa sua DAO.

Resumindo, cada classe vai ter a sua função direitinho…

a ConnectionManager vai obter a conexão com o banco de dados
a Contato vai mapear sua entidade do banco de dados
a ContatoDAO vai definir todos os métodos de persistência que estarão disponíveis para utilização (de modo que haja um padrão para todas as classes que a implementam)
e a ContatoDB vai realizar a implementação desta interface, sobrescrevendo os métodos definidos na interface, utilizando-os de acordo com suas regras de negócio e obdecendo a definição da tabela “Contato” do seu banco de dados (ou seja, no final das contas, apenas ESSA CLASSE vai conhecer sua tabela no banco de dados).

Espero ter ajudado…

Depende dos seus conceitos de OO … lol… se forem como os meus isso que vc está fazendo só tem um nome: Gambiarra!

O principio fundamental de OO é o principio de separação de responsabilidades. Em inglês: Separation of Concerns Principle (SoC). É este principio que dá origem à propria OO. O primeiro corolário deste principio é um outro pincipio o: Principio do Encapsulamento. (mais sobre isso aqui)

O ponto é que os seus objetos devem ser desenhados com certas responsabilidades e ao mesmo tempo com poucas responsabilidades. (procure por CRC cards para mais info). Então, se um objeto assume muitas responsabilidades isso é sinal de um design defeituoso.

Se vc tiver um objeto de dados e um DAO vc tem dois objetos cujas responsabilidades são bem idenificadas, não se misturam e são independentes. O objeto de dados transporta dados e faz operações simples sobre eles, o DAO persiste esses dados em algum lugar de forma a preservá-los.

Quando vc faz o DAO herdar o objeto de dados vc está misturando as coisas. Vc está atribuindo responsabildiade ao DAO de portar dados e ao objeto de dados de saber persistir seus dados. Embora isso seja possivel (veja o padrão ActiveRecord) isso tem custos. Esses custos são elevados porque vc está violando explicitamente o SoC. Pode parecer melhor e mais facil, mas não é.

Quando vc define o DAO como métodos estáticos vc está espalhando a responsabilidade por um monte de métodos em vez de os agrupar em um só tipo de objeto. Aqui é o problema inverso. Vc separou demais as responsabilidades. Na hora que um método mudar vc não vai lembrar de mudar o outro e o sistema vai ficar com problemas. Incluindo tudo num so objeto vc mantém a caracteristica mais importante de OO: encapsulamento.

Então marcelo… essa abordagem do contato ter um método salvaContato() ou simplesmente
salva() existe e se chama Active Record.
Só que nessa abordagem não há herança, vc simplesmente adiciona esses métodos no contato mesmo.

Essa abordagem é bem menos comum no mundo Java do que a do DAO, mas é bastante
interessante…

[]'s

Ola,

faz uma coisa do tipo

no pacote

package br.com.aplicacao.dominio

public class Contato{

//aqui terá os seus metodos getters e setters
.
.
.
}

neste mesmo pacote vc tem outras classes do dominio de sua aplicacao

outro pacote seria esse

package br.com.aplicacao.dao

public interface ContatoDAO{

//aqui vc determina os metodos adicionar,remover,atualizar entre outros

}

public class ContatoDAOImpl implements ContatoDAO{

// aqui a implementacao dos metodos definidos na interface

}

e um outro q iria usar tudo isso poderia ser um servlet por exemplo

package br.com.aplicacao.servlets

public class CadastrarContato extends HttpServlet{

//no doPost realize a operacao de cadastrar

public void doPost(HttpServletRequest request, HttpServletResponse response)

//crie um objeto contato e jogue os valores dos seus atributos
//instancie a classe ContatoDAOImpl usando como referencia ContatoDAO
//chame o metodo cadastrarContato e passe o objeto recem criado

}

espero ter ajudado!

[quote=jt_holanda]Ola,

faz uma coisa do tipo

no pacote

[code]package br.com.aplicacao.dominio

public class Contato{
//aqui terá os seus metodos getters e setters
.
}[/code]neste mesmo pacote vc tem outras classes do dominio de sua aplicacao

outro pacote seria esse

[code]package br.com.aplicacao.dao

public interface ContatoDAO{

//aqui vc determina os metodos adicionar,remover,atualizar entre outros
}[/code][code]public class ContatoDAOImpl implements ContatoDAO{

// aqui a implementacao dos metodos definidos na interface
}[/code]
e um outro q iria usar tudo isso poderia ser um servlet por exemplo

[code]package br.com.aplicacao.servlets

public class CadastrarContato extends HttpServlet{

//no doPost realize a operacao de cadastrar

public void doPost(HttpServletRequest request, HttpServletResponse response)

//crie um objeto contato e jogue os valores dos seus atributos
//instancie a classe ContatoDAOImpl usando como referencia ContatoDAO
//chame o metodo cadastrarContato e passe o objeto recem criado
}[/code]espero ter ajudado![/quote]

Chame o repositório (que você chama de DAO) de dentro das classes de negócio, não das servlets.