Olá, pessoal. Tudo bom?
Tenho pesquisado um pouco sobre camada service mas ainda não entendi muito bem.
Nesse tópico aqui: http://www.guj.com.br/java/261498-duvida-simples-sobre-mvc
O amigo Eduardo diz que não é bom chamar a DAO no controller, e que seria melhor usar um Service.
Mas realmente não entendi o porquê disso.
Estou acostumado a injetar a DAO em um controller mesmo.
Aqui no trabalho até peguei um exemplo.
Uma camada service
[code]@Service
public class DespesaService { @Inject @Qualifier(“despesaDao”)
private DespesaDao dao;
public void save(Despesa despesa) {
dao.save(despesa);
}
public void remove(Despesa despesa) {
despesa.setStatus(StatusDespesa.REMOVIDA);
dao.save(despesa);
}
public Despesa findById(Serializable id) {
return dao.findById(id);
}
public List<Despesa> listBy(Solicitacao solicitacao) {
return dao.listBy(solicitacao);
}
}[/code]
que é chamada no controller ao invés dele chamar a DAO diretamente.
a controler só gerencia o fluxo das informações ela não deve conter regras de negocio e persistencia em seu conteudo…
o ideal é Controller -> Service > VO > DAO se achar mais agradavel remove o VO… e coloca regra de negocio no Service mesmo (acho feio) mas nao chega a ser uma má pratica…
tem N maneiras de implementar a mesma coisas… mas aumenta a complexidade dependendo de quantas camadas existe a aplicação…
Exemplo:
Tenho sistema de crud de cliente, o sistema pode fazer os cadastros/pesquidas pelo Site e pelo WebService.
As regras de negócios é a mesma para o site e para WebService, como faço para não duplicar regras de negócios?
[quote=darklordkamui]a controler só gerencia o fluxo das informações ela não deve conter regras de negocio e persistencia em seu conteudo…
[/quote]
Correto.
[quote=Kura]Olá, pessoal. Tudo bom?
Tenho pesquisado um pouco sobre camada service mas ainda não entendi muito bem.
Nesse tópico aqui: http://www.guj.com.br/java/261498-duvida-simples-sobre-mvc
O amigo Eduardo diz que não é bom chamar a DAO no controller, e que seria melhor usar um Service.
Mas realmente não entendi o porquê disso.
Estou acostumado a injetar a DAO em um controller mesmo.
Aqui no trabalho até peguei um exemplo.
Uma camada service
[code]@Service
public class DespesaService { @Inject @Qualifier(“despesaDao”)
private DespesaDao dao;
public void save(Despesa despesa) {
dao.save(despesa);
}
public void remove(Despesa despesa) {
despesa.setStatus(StatusDespesa.REMOVIDA);
dao.save(despesa);
}
public Despesa findById(Serializable id) {
return dao.findById(id);
}
public List<Despesa> listBy(Solicitacao solicitacao) {
return dao.listBy(solicitacao);
}
}[/code]
que é chamada no controller ao invés dele chamar a DAO diretamente.
Alguem poderia tentar me explicar a vantagem?
Grande abraço e obrigado a todos![/quote]
Sinceramente não vejo problema algum injetar o DAO direto no Controller,o que eu vejo muito por ai é essa camada Service sendo um mero delegate pro DAO.Nos meus projetos uso Controller–>DAO
O próprio exemplo que vc colocou ilustra isso:o que essa camada Service está fazendo que não pode ser feito direto no Controller?
[quote=raf4ever]Sinceramente não vejo problema algum injetar o DAO direto no Controller,o que eu vejo muito por ai é essa camada Service sendo um mero delegate pro DAO.Nos meus projetos uso Controller–>DAO
O próprio exemplo que vc colocou ilustra isso:o que essa camada Service está fazendo que não pode ser feito direto no Controller?[/quote]
Bom, isso é uma questão de organização e design, eu vejo a camada de serviço como uma coisa boa, ela diz o que o serviço faz, mantendo uma API limpa, abstraindo a lógica de negócio no model.
O próprio Eric Evans, autor do livro Domain-Driven Design, diz que ela deve existir.
[quote]Application Layer [his name for Service Layer]: Defines the jobs the software is supposed to do and directs the expressive domain objects to work out problems. The tasks this layer is responsible for are meaningful to the business or necessary for interaction with the application layers of other systems. This layer is kept thin. It does not contain business rules or knowledge, but only coordinates tasks and delegates work to collaborations of domain objects in the next layer down. It does not have state reflecting the business situation, but it can have state that reflects the progress of a task for the user or the program.
Domain Layer (or Model Layer): Responsible for representing concepts of the business, information about the business situation, and business rules. State that reflects the business situation is controlled and used here, even though the technical details of storing it are delegated to the infrastructure. This layer is the heart of business software.[/quote]
Essa citação foi retirada de um post do Martin Fowler sobre Anemic Domain Model, mesmo o post aqui não sendo sobre isso, essa citação serve como exemplo
[quote=Kura]Olá, pessoal. Tudo bom?
Tenho pesquisado um pouco sobre camada service mas ainda não entendi muito bem.
Nesse tópico aqui: http://www.guj.com.br/java/261498-duvida-simples-sobre-mvc
O amigo Eduardo diz que não é bom chamar a DAO no controller, e que seria melhor usar um Service.
Mas realmente não entendi o porquê disso.
Estou acostumado a injetar a DAO em um controller mesmo.
Aqui no trabalho até peguei um exemplo.
Uma camada service
[code]@Service
public class DespesaService { @Inject @Qualifier(“despesaDao”)
private DespesaDao dao;
public void save(Despesa despesa) {
dao.save(despesa);
}
public void remove(Despesa despesa) {
despesa.setStatus(StatusDespesa.REMOVIDA);
dao.save(despesa);
}
public Despesa findById(Serializable id) {
return dao.findById(id);
}
public List<Despesa> listBy(Solicitacao solicitacao) {
return dao.listBy(solicitacao);
}
}[/code]
que é chamada no controller ao invés dele chamar a DAO diretamente.
Alguem poderia tentar me explicar a vantagem?
Grande abraço e obrigado a todos![/quote]
O seu exemplo não condiz com a sua conversa. O exemplo mostra um DAo sendo injetado num Service e vc fala de injetar Dao em “Controller” ( Controller não é um padrão, é uma parte de um padrão).
então afinal , do que estamos falando ?
Injetar o dao no service é tranquilo.
Injetar o service no objeto da camada de apresentação que cuida de responder às ações do usuário é tranquilo ( no struts chama-se Actions, em outros frameworks têm outros nomes )
Injetar o dao no objeto da camada de apresentação é realmente errado. Está sendo pulada a camada de serviços. A menos, é claro, que nesse sistema não exista essa camada ( mas normalmente existe)
Eu mostrei esse código onde está sendo injetado uma DAO justamente para tentar entender um pouco o porquê de colocar a service entre o controller e o dao.
Meu problema é justamente o conceito.
Com os meus conhecimentos atuais, eu poderia injetar a DAO no controller e utiliza-la do jeito que o service a está utilizando.
Ou seja… Se na minha view, eu tenho um botão salvar, meu controller chamaria o dao.save(obj);
Li as respostas de todos e só não respondi até agora pq estou tentando chegar a uma conclusão pq entendi por uma resposta que era uma questão de design.
Mas design pra mim é uma questão de legibilidade e, ao menos nesse caso, só me parece acrescentar mais complexibilidade.
Mas enfim. A verdade é que acho que estou tentando entender melhor o que os amigos quiseram dizer para desvendar o mistério. =P
[quote=Kura]
Mas enfim. A verdade é que acho que não entendi o que os amigos quiseram dizer e ainda estou tentando desvendar o mistério. =P
Hoje eu ainda entendo o fluxo do MVC como:
view chama controller que chama model/dao[/quote]
Esqueça o MVC.
O problema aqui é Camadas. O que vc está fazendo de atrelar o dao diretamente ao “controler” funciona para coisas simples como salvar. O CRUD básico da vida.
Mas em coisas mais complexas o DAO não é suficiente. Existem casos onde vc precisa usar mais que um DAO ao mesmo tempo gerando informações ou lendo informações em diferentes entidades/tabelas. É também comum fazer validações de regras.
O exemplo clássico é a transação entre contas. Vc precisa saber quais a contas, se elas existem, se a transação pode ser feita, e gerar movimentos em cada conta. É a tipica operação que gera mais do que um objeto a partir de mais do que um objeto.
Onde vc colocaria todo este código que le e escreve em vários DAO ? Na apresentação ? Não. A UI tem que delegar este tipo de coisa. O que a UI sabe é que uma transação precisa ser feita, ela não sabe como (SRP - Single Responsability Principle).
Portanto, pelo simples fato de precisar orquestrar código mais complexo vc precisa de uma camada a mais. Esta camada é muito ténue quando está na parte de cadastros, mas é muito rica quando vc está na parte de processos. E todos os sistemas têm uma parte de processos ( é por isso que eles existem). Ora o processamento fica no Service. O dao é apenas um mediador com o banco de dados.
Vc está tomando a parte pelo todo achando que se o dao no controler funciona para o save, funciona para tudo. Não é verdade. E por isso a necessidade do service.
Uma vez o service posicionado na sua arquitetura ele lhe dá outras vantagens como por exemplo, poder usar services remotos ( seja EJB ou webservices ou qq outra coisa) o que possibilita que a UI esteja rodando em uma máquina e o resto em outra.
A UI é simplesmente uma desenho bonito paras as pessoas entenderem o que estão fazendo. E isso pode mudar. Mais do que a aplicação em si mesma. Afinal transações bancárias é um negocio mais velho que nós e existem N diferentes UI para isso por ai. Desde o home banking até aos caixas automáticos. A apresentação e interação é diferente, mas o que se faz é sempre a mesma coisa. Então a camada se service lhe permite também capacitar a sua aplicação com invocação remota e portanto torná-la uma aplicação distribuída. Fazer isso com o DAO seria o caos.
[quote=sergiotaborda]
Portanto, pelo simples fato de precisar orquestrar código mais complexo vc precisa de uma camada a mais. Esta camada é muito ténue quando está na parte de cadastros, [/quote]
Exatamente,o que eu mais vejo por ai é a galera colocando essa camada a mais sem ter necessidade pra isso, só pra ‘manter o padrão’,tornando o Service um mero delegate pro DAO.
sergiotaborda,
cara… muito obrigado. Com a tua ajuda e umas leituras depois, consegui finalmente entender melhor o service.
isso mudou mto meu pensamento pq ha anos eu penso no “controller” (e agora eu entendo bem melhor o pq vc se refere como objeto da camada de apresentação) como o lugar onde devo colocar minha logica de negocio.
depois dessa conversa, se é que consegui entender mais ou menos (não me mate se entendi tudo errado!), ele funciona mais como um controle de fluxo da view mesmo.
colocando as lógicas numa camada service, eu posso substituir um managed bean do jsf pelo correspondente do spring sem mudar nada alem disso.
também consegui entender melhor o comentário de todos os outros.
muito obrigado a todos!
todos foram de grande ajuda!
[quote=raf4ever][quote=sergiotaborda]
Portanto, pelo simples fato de precisar orquestrar código mais complexo vc precisa de uma camada a mais. Esta camada é muito ténue quando está na parte de cadastros, [/quote]
Exatamente,o que eu mais vejo por ai é a galera colocando essa camada a mais sem ter necessidade pra isso, só pra ‘manter o padrão’,tornando o Service um mero delegate pro DAO.
[/quote]
Foi justamente por ter visto o service apenas como delegate para o dao que nao entendi inicialmente, pois pra mim parecia algo desnecessário, adicionando apenas complexidade
Agora uma pergunta com relação a design.
Se em um dos casos do meu sistema eu preciso aplicar o service pelo fato dele nao servir soh como delegate, por uma questao de design eh melhor eu aplicar a camada em todos os outros casos, mesmo que nesses outros a service va servir soh como delegate?
[quote=Kura]Agora uma pergunta com relação a design.
Se em um dos casos do meu sistema eu preciso aplicar o service pelo fato dele nao servir soh como delegate, por uma questao de design eh melhor eu aplicar a camada em todos os outros casos, mesmo que nesses outros a service va servir soh como delegate?[/quote]
Se for uma necessidade pontual,acredito que seja melhor criar conforme for necessário.
Então eu posso ter, no mesmo sistema, dao sendo injetado em um objeto da camada de apresentação (pq eu não terei lógica de negócio) e, num outro obj de apresentação eu trabalhar com service?
não há questões com relação à boas práticas?
[quote=Kura]Então eu posso ter, no mesmo sistema, dao sendo injetado em um objeto da camada de apresentação (pq eu não terei lógica de negócio) e, num outro obj de apresentação eu trabalhar com service?
não há questões com relação à boas práticas?[/quote]
Te respondo essa pergunta com outra.
Pra mim, se eu uso service em uma por necessidade, fica mais legível colcar o service em todos os outros casos. Mesmo que alguns deles sejam apenas para delegar dao.
Mas… eu sempre quero saber as melhores práticas, né? As vezes eu acho isso e não tem nada a ver =x
[quote=Kura]Pra mim, se eu uso service em uma por necessidade, fica mais legível colcar o service em todos os outros casos. Mesmo que alguns deles sejam apenas para delegar dao.
Mas… eu sempre quero saber as melhores práticas, né? As vezes eu acho isso e não tem nada a ver =x[/quote]
Eu concordo com você.
Ainda mais se você não estiver desenvolvendo sozinho, imagine que você tem uma equipe. Entra uma pessoa nova e ela vê esse padrão em uma tela. Controller > Service > DAO.
Aí em outra situação a pessoa analisa uma outra funcionalidade e vê o DAO injetado direto no Controller. É claro que funciona, mas isso pode confundir, manter o padrão é sempre bom (na minha opinião).
Outra situação:
Imagine que um service é um mero delegate pra um DAO, e por algum motivo, é decidido que a regra de negócio ali tem que mudar, você precisa acessar mais tabelas, fazer mais consistências e etc. Só aí vai criar o service? E depois vai substituir todas as chamadas ao DAO para chamadas ao Service? Manter o padrão nesse caso também vai facilitar a manutenção do seu sistema.