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
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…
A
AdrianoSB
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?
a controler só gerencia o fluxo das informações ela não deve conter regras de negocio e persistencia em seu conteudo…
Correto.
Errado,regra de negócio vai no Model
R
raf4ever1 like
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
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!
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?
R
Rodrigo_Sasaki
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?
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.
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.
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
S
sergiotaborda
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
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!
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)
K
Kura
Muito obrigado a todos.
Sergio,
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
Hoje eu ainda entendo o fluxo do MVC como:
view chama controller que chama model/dao
S
sergiotaborda
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
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.
R
raf4ever
Me dê um exemplo disso.
R
raf4ever
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,
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.
K
Kura
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!
K
Kura
raf4ever:
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,
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.
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
K
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?
K
Kura
Ops. Enviei duas vezes
R
raf4ever
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?
Se for uma necessidade pontual,acredito que seja melhor criar conforme for necessário.
K
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?
R
Rodrigo_Sasaki
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?
Te respondo essa pergunta com outra.
Como você acha que fica mais organizado?
K
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
R
Rodrigo_Sasaki
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
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.
K
Kura
Pois é. Eu pensei isso tb quando vi o post do Sérgio (não lembro se foi ele que falou) que está cansado de ver service como delegate dao. Pensei que talvez isso fosse feito pensando na possibilidade de colocar uma lógica futuramente.
Mas é isso então, cara.
Sinto que nessa thread eu passei de não saber nem o que é service pra entender muito bem (na medida do possivel, né? pq nem apliquei ainda), como e quando utilizar.
Muito obrigado, Rodrigo. Obrigado mesmo!
E muito obrigado a todos!
R
raf4ever
Rodrigo Sasaki:
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
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.
Eu tinha dado uma opinião contrária,mas preciso concordar com vc.
G
gomesrod
Kura:
Sinto que nessa thread eu passei de não saber nem o que é service pra entender muito bem (na medida do possivel, né? pq nem apliquei ainda), como e quando utilizar.!
Quero aproveitar para deixar um elogio para esse tópico.
Uma discussão saudável, simples e informativa com um resultado excelente: pelo menos 2 pessoas abriram a mente para novas maneiras de pensar em organização e qualidade do código.
Queria que as pessoas que desenvolveram o sistema que estou dando manutenção hoje tivessem lido isso! kkkkk
É sério, estou vivendo na prática as consequências de se achar que as regras de negócio não precisam ficar isoladas, pois o sistema “é simples”. Agora o sistema cresceu, existem diversas funcionalidades que usam as mesmas regras e elas estão replicadas em todos os pontos. Fora que algumas regras estão na apresentação (controller) enquanto outras estão no DAO, dependendo de quem foi mantendo ao longo do tempo!
Parabéns ao Sérgio e ao Rodrigo, pois explicaram bem os problemas envolvidos nessa decisão ao invés de simplesmente tentar impor por ser padrão.
R
Rodrigo_Sasaki
gomesrod:
Quero aproveitar para deixar um elogio para esse tópico.
Uma discussão saudável, simples e informativa com um resultado excelente: pelo menos 2 pessoas abriram a mente para novas maneiras de pensar em organização e qualidade do código.
Queria que as pessoas que desenvolveram o sistema que estou dando manutenção hoje tivessem lido isso! kkkkk
É sério, estou vivendo na prática as consequências de se achar que as regras de negócio não precisam ficar isoladas, pois o sistema “é simples”. Agora o sistema cresceu, existem diversas funcionalidades que usam as mesmas regras e elas estão replicadas em todos os pontos. Fora que algumas regras estão na apresentação (controller) enquanto outras estão no DAO, dependendo de quem foi mantendo ao longo do tempo!
Parabéns ao Sérgio e ao Rodrigo, pois explicaram bem os problemas envolvidos nessa decisão ao invés de simplesmente tentar impor por ser padrão.
Ah, eu sei bem como é isso. Na verdade é realmente complicado entender os padrões até você dar de cara na parede igual você está fazendo agora (ou igual eu já fiz também).
Já passei por uns projetos que nem pareciam que utilizavam uma linguagem orientada a objetos
Você por ter bastante experiência já entende que essa complexidade a mais vai te poupar muitas horas de trabalho e dor de cabeça.
Agora com certeza o Kura vai passar por situações parecidas (como todos nós passamos, não é mesmo?), e vai ver as vantagens e desvantagens de cada decisão tomada.
K
Kura
Rodrigo Sasaki:
gomesrod:
Quero aproveitar para deixar um elogio para esse tópico.
Uma discussão saudável, simples e informativa com um resultado excelente: pelo menos 2 pessoas abriram a mente para novas maneiras de pensar em organização e qualidade do código.
Queria que as pessoas que desenvolveram o sistema que estou dando manutenção hoje tivessem lido isso! kkkkk
É sério, estou vivendo na prática as consequências de se achar que as regras de negócio não precisam ficar isoladas, pois o sistema “é simples”. Agora o sistema cresceu, existem diversas funcionalidades que usam as mesmas regras e elas estão replicadas em todos os pontos. Fora que algumas regras estão na apresentação (controller) enquanto outras estão no DAO, dependendo de quem foi mantendo ao longo do tempo!
Parabéns ao Sérgio e ao Rodrigo, pois explicaram bem os problemas envolvidos nessa decisão ao invés de simplesmente tentar impor por ser padrão.
Ah, eu sei bem como é isso. Na verdade é realmente complicado entender os padrões até você dar de cara na parede igual você está fazendo agora (ou igual eu já fiz também).
Já passei por uns projetos que nem pareciam que utilizavam uma linguagem orientada a objetos
Você por ter bastante experiência já entende que essa complexidade a mais vai te poupar muitas horas de trabalho e dor de cabeça.
Agora com certeza o Kura vai passar por situações parecidas (como todos nós passamos, não é mesmo?), e vai ver as vantagens e desvantagens de cada decisão tomada.
Rapaz…
Estou há menos de 3 meses trabalhando profissionalmente com JAVA, mas, antes disso, eu trabalhei quase 3 anos com vb3!!!
Foram tempos obscuros, cara. Sério. Num determinado dia eu recebi a notícia de que “a quantidade de digitos da nota fiscal iria mudar”. Acrescentar 3 dígitos, sabe?
Numa empresa que tem vb3 como linguagem domintante… e que tem mais de 130 sistemas!! E cada view de TODOS os sistemas tinha varios format(“000000”)!
Ou seja formats * views * sistemas.
Fiquei meses fazendo isso.
Por mais que eu não tenha xp nenhuma com JAVA, eu entendo muito bem que decisões tem consequências.
Talvez por isso tenha desenvolvido esse perfil de procurar sempre a melhor forma de fazer e não só aceitar o que está ali e copiar.
huahuahuhauhahuhah
S
sergiotaborda
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?
Eu queria focar neste ponto de ser permissivel que em alguns pontos o dao seja injetado diretamente ou que alguns services são apenas delegates para o dao.
A primeira coisa é: se o seu service é apenas um delegate, o seu sistema está errado.
Peguemos o exemplo clássico do save. A apresentação chama o save do service que chama o save do dao. A apresentação montou o objeto e enviou. Quem está garantindo que o save pode ser feito ? quem está validando ? quem abriu a transação ? não ah transação ?
O service precisa validar. E só por isso a responsabilidade do service já é diferente da do dao. Isso faz com que código que apenas delegam sejam sinal de que falta alguma coisa no código.
O outro lado da moeda é fazer uma pesquisa. O famoso listar. A UI monta o filtro e passa para o service que delega ao dao. O dao retorna o resultado e vem tudo para cima até à ui.
Bom, em tese poderíamos validar o filtro. Isso é raro, mas às vezes é necessário. Mas fora isso não ha muito a fazer. Aqui realmente parece que apenas ha uma delegação. E de fato é isso mesmo. Está errado ?
Não está errado. As camadas foram desenhadas assim. A camada de apresentação não deve enxergar a camada de integração (Dao) ela só vê a camada de dominio (Service).
A pura e simples delegação é oca. É quase uma violação do DRY. Será possivel desenvolver de outra forma, para que não seja necessária a delegação ?
Sim. Basta adicionar à camada de domínio uma outra classe que esteja no mesmo nivel do service, que a ui possa acessar, mas que não é um service. Esse padrão é o Repositório. Por baixo em algum ponto pode estar o DAO ou outra coisa qualquer, mas do ponto de vista da UI o dao simplesmente não existe. Se corresponde ao cliente saber que existe um banco de dados. Ele simplesmente não deve saber disso.
Portanto, existe outras técnicas e padrões que realmente se ajustam melhor do que o design ui > service > dao, mas se o design já está fixo nesse padrão, então realmente vai aparecer um pouco de delegação.
Sendo que ela está lá, é válido pular a camada de service e ir diretamente no dao ? Não. Isso viola a separação de camadas. Cada camada só conhece a que está imediatamente abaixo. Não conhece a de cima e não conhece as mais abaixo que a seguinte. Porque alguem iria violar este principio ? Simplesmente não é saudável tentar.
A única maneira de driblar este problema é introduzir o conceito de repositório, mas isso significa sair do design ui> service > dao e pode ter implicações de o sistema é distribuído.
K
Kura
Obrigado, Sergio.
Foi um post bastante informativo e me ajudou a solidifcar ainda mais os conceitos.
Ainda me serviu de ancora para pesquisar e entender mais sobre o Repositório.
Grande abraço!
G
gambazinho
no final das contas isso vai depender do arquiteto/líder técnico responsável pelo projeto.
mas aqui no meu atual emprego foi onde vi uma arquitetura mais coerente, temos de maneira bem isolada:
camada de apresentação: JSF
camada de persistencia: beans
camada de Negócio: EJBs
as coisas estão bem separadas.
J
JoseIgnacio
São tópicos como esse discutindo o sexo dos anjos que ajudam a criar essas monstruosidades.
É o que estava falando em um outro tópico.
Você pode usar a melhor linguagem e contratar os melhores programadores OO, mas se o profissional não conhece o domínio do sistema que está desenvolvendo (como a maioria que opinou nessa thread) não será capaz de chegar a uma solução elegante, porque lhe falta visão sobre o problema.
A
apalmeira
Pessoal achei esse tópico muito interessante.
Estou migrando para o java EE e gostaria de saber se eu entendi corretamente o que os amigos explicaram.
(1) VIEW (JSF) -> (2) CONTROLER-MB(CDI) -> (3) SERVICE (EJB - @Stateless/@Statefull) -> (4) DAO (EJB - @Stateless/@Statefull)
TRATAR AÇÕES DO JSF, CICLO DE VIDA ETC.
SE NECESSÁRIO MIGRAR PARA OUTRA TECNOLOGIA BASTA CRIAR OUTRA CLASSE SEM ALTERAR O RESTANTE DO FLUXO.
REGRA DO NEGÓCIO VALIDAÇÕES ETC.
PODE TER DAO PARA OPERAÇÕES QUE UTILIZAM BANCO DE DADOS.