A questão é:
[color=blue][size=15]O meu Control pode instanciar um objeto da classe DAO ?[/size][/color]por ex:
DaoPaciente daoPac = new DaoPaciente();
List resultados = daoPac.consultarTodos();
Iterator<Paciente> iterador = resultados.iterator();
while(iterador.hasNext()){
pac = iterador.next();
//adiciono o objeto inteiro no jcb, para facilitar a recuperação
//dos dados. E para exibir na tela, tem o método toString
//da classe Paciente, no método há comentários com a explicação
//do que ele faz.
jcbPacientes.addItem(pac);
}
Ou o correto seria que isso fosse feito da seguinte forma:
1: O Control instancia um objeto da minha classe de negócio e chama um método.
2: Em seguida este método da minha classe de negócio instancia um objeto da classe DAO e chama o método desejado da classe DAO.
3: O método da DAO retorna para a classe de Negócio e a classe de Negócio retorna para o Control e este por sua vez para a classe View.
Cara na minha visão tem que ser da segunda forma, por que se for da primeira destroi totalmente seu modelo em camadas.
Se você tem uma camada intermediária então não tem porque acessar diretamente a camada mais baixa. Isso cria uma Dependencia cíclica que vai aumentar o acoplamento da sua aplicação.
Na teoria do MVC, o DAO é apenas um padrão de persistência adotado. Creio que não é responsabilidade do Controller interagir com o Dao diretamente.
View
Controller
Model -> utiliza Dao como persistencia
O Dao é de responsabilidade do Model. A forma como o model busca suas informações em diferentes meios de persistência ou armazena dados, não deve ser mostrada ao Controller nem a View. Assim as camadas ficam isoladas e desacopladas.
O Controller é responsável por atender as chamadas da View e acionar o Model. O Model possui os objetos de negócio e possui os meios de persistência (dao).
Então isso levaria a ter objetos (value objects) no model, que seriam disponibilizados ao controller. O controller preenche os value objects e aciona métodos do modelo.
Nesta visão, o Viewer não poderia acessar os value objects do Model. Porém na prática, o que se vê geralmente é a transição de objetos do model (pojos hibernate) trafegando em todas as camadas até a view… Isso pelo fato que geralmente os arquitetos colocam as camadas juntas em um mesmo servidor, fazendo apenas um pacote para a aplicação (ear).
Mas se um dia forem separar as camadas em servidores diferentes, haverá alguns problemas relacionados à compatibilidade destes value objects duplicados em camadas diferentes.
Então, te respondendo, eu ficaria com sua segunda forma.
Não tenho visto o pessoal criar Value Object mais. … eles sobem com o @Entity até a camada de apresentação, o que na minha visão é um furo de arquitetura.
Mas se seu arquiteto concordar, é o que deve ser feito.
Eu creio que Entity é diferente de Value Object.
O value object seria uma caixinha de informações leve, sem métodos de negócio, apenas para transitar os dados.
A Entity ficaria sempre la em baixo, no model.
Caraval, obrigada pela resposta, mas a questão agora é a seguinte:
[color=red]Eu utilizo JPA, as minhas classes de negócios são Entity, eu queria saber se há algum problema em colocar métodos nessas classes do meu pacote Model (que são @Entity) e que a partir desses métodos seja feita a chamada aos DAO’s[/color]
Você pode e na teoria seria o mais correto. Por que a entidade seria auto-contida. Ela representaria os dados, teria os metodos de negócio e ainda seria persistível.
Ficaria semelhante ao Entity Bean BMP que deu origem as ideias do JPA.
Agora imagine que você tenha a Entity Cliente.
E você precisa de um método recuperarListaAnivesariantesMes(). Ficaria estranho você ter de instanciar uma classe Cliente (criando assim um novo objeto persistivel) e chamar este metodo que retornaria uma lista de Clientes que estão fazendo aniversário. Ao passo que tambem este método poderia ser estático e você chamaria Cliente.recuperarListaAniversariantesMes().
Para evitar esta confusão de uma classe Cliente recuperar vários clientes que fazem aniversário, costuma-se transferir os métodos de negócio para uma classe Business. Tendo assim mais uma classe chamada agora de ClienteBusinessObject ou ClienteBO, a qual conteria o método.
Mas isso faz agora com que a classe Entity Cliente passe a ser apenas uma entidade do banco de dados mesmo. Não mais um objeto de negócio.
Nas aplicações que desenvolvo… costumo fazer assim:
Controller -> Service -> DAO
As entidades (@Entity) possuem apenas getters e setters… e existem no controller, service ou dao…
Para um efeito mais prático… do que chamar o service e o service simplismente fazer a mesma chamada ao DAO… eu costumo cortar caminho e fazer:
Controller -> DAO
Isso é o que eu costumo fazer… mas para seguir a filosofia mais purista… o melhor é a alternativa anterior…
Não acho válido colocar chamadas de DAO no seu Entity… um dos motivos é o que o Carval citou…
Entao fica mais ou menos assim (pseudocodigo):
class MeuController {
MeuService meuService;
public void listar(){
List<MinhaEntidade> lista = meuService.findAll();
}
}
class MeuService {
MeuDAO dao;
public List<MinhaEntidade> findAll(){
return dao.findAll();
}
}
class MeuDAO {
public List<MinhaEntidade> findAll(){
return query("from MinhaEntidade");
}
}
@Entity
class MinhaEntidade {
//campos getters e setters apenas
}
Acho que agora seu projeto já está crescendo… talvez seja a hora de adicionar o Spring nele para fazer a injeção de dependência…
Rogel e Carval, entendi o que vcs falaram, então eu criaria uma outra classe que ficaria entre o Controller e o DAO. E esta classe intermediária costuma ser chamada de Business. Correto?? É isso mesmo?
No caso de uma tela de cadastro por exemplo:
1 - No botão Cadastrar, no ActionPerformed eu instancio um objeto Paciente da minha classe @Entity (por ex.), faço os set’s.
2 - Feito isso, instancio um objeto da classe BusinessPaciente e este chama o método cadastrar da classe BusinessPaciente levando como parâmetro o objeto Paciente criado.
3 - Por sua vez o método cadastrar, da classe BusinessPaciente instancia um objeto da classe DaoPaciente levando tbm o objeto Paciente como parâmetro.
4 - Já na classe DaoPaciente e no respectivo método é feito o seu papel junto ao BD.
[color=red]Está correto???[/color] Muito obrigada pelas respostas!!
[color=red]1 - No botão Cadastrar, no ActionPerformed eu instancio um objeto Paciente da minha classe @Entity (por ex.), faço os set’s.[/color] Tem frameworks que fazem isso…
Depois você dá uma olhada no Spring… ele faria o “instanciamento” dos objetos (controller, bussiness, daos) pra vc…
Olha só, a forma de organização dos seus pacotes não necessariamente faz você abandonar o modelo MVC que está utilizando.
O MVC é um modelo arquitetural de software. Os seus pacotes são apenas uma forma de organização. São apenas pastas para organizar seu software.
O MVC é adotado para você isolar as camadas do software. Então você deve se preocupar com isso e não deixar que ninguém fure sua arquitetura.
Você fura seu modelo MVC se fizer com que a view ou controller acesse diretamente objetos do DAO.
Ou se a View acessar diretamente os objetos do Model.
View -> Controller -> Model -> Dao
A ‘camada’ Business continua sendo um subsistema da ‘camada’ Model. Mesmo que voce decida deixar o ‘pacote’ business dentro ou fora do ‘pacote’ Model, a camada business ainda fica dentro da camada Model.
Pacote é uma coisa. Visão lógica das camadas é outra.
A organização de pacotes pode seguir ou não a organização lógica do MVC.
MVC:
Agora, entendi que você está modelando as camadas de seu software. Se teu software vai ser de grande porte, ou apenas um projeto simples, já pensou em adotar SOA?
A experîência me mostrou que geralmente com o tempo os desenvolvedores acabam torando a arquitetura proposta. Pois não há investimentos por parte da empresa na revisão de código que deveria sempre ser feita.
Então adotando SOA, você organizará seu software de uma forma que ficará mais difícil de furar a arquitetura.
Você não precisa adotar todos os conceitos. Mas se você isolar sua camada de negócio em webservices, você terá uma arquitetura mais forte.
Tudo fica atrás de um webservice. Imagina que tua tela grave os dados de um cliente. Se um dia houver uma integração com outro software externo que enviará também dados de novos clientes, você disponibiliza para ele uma interface de seu webservice. Isto é uma das vantagens por exemplo.
É bem diferente e a principio parece dar mais trabalho.
Mas o que você terá de fazer é usar a tag @Webservice
CarvalR2, muito obrigada pelas respostas!
Fica a dica de utilizar SOA, mas em um próximo projeto, pois este que estou fazendo é Desktop…
Muito obrigadaaaa…