| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 21/06/2007 18:23:21
|
Rafael Nunes
Moderador
![[Avatar]](/images/avatar/d072677d210ac4c03ba046120f0802ec.png)
Membro desde: 09/10/2003 13:41:06
Mensagens: 2833
Localização: sao bernardo do campo
Offline
|
ronildobraga wrote:Eu nao achei pratica essa solução, e se eu mudar a logica de acesso a dados, por exemplo: Hoje eu uso hibernate mas amanha eu gostaria de usar JDBC, seguindo o Active Record eu teria de configurar novamente todos os objetos de dominio, nao achei muito inteligente nao
Rafael Nunes wrote: No próprio livro Fowler diz que active record é uma boa solução para sistemas que não tenham uma lógica de negócio muito complexa, tipo CRUDs, e sugere que para domínios com relacionamentos mais complexos, seja utilizado alguma forma de Data Mapper, como DAO por exemplo.
O exemplo que eu dei utiliza as duas estratégias, porém ao invés de o objeto de domínio conter a lógica de acesso a dados, ele delega essa responsabilidade para um Data Mapper.
Pode substituir na frase acima, lógica de negócio complexa por estratégias arquiteturais mutáveis.(E particularmente, já ouvi bastante esta questão de 'e se eu trocar de banco', 'e se eu trocar de mecanismo de persistência', 'e se eu trocar o SO do meu servidor'), mas na prática nunca vi e nem ouvi falar disso, a não ser para softwares que já nascem com a intenção de independência de plataforma. E sistemas simples, eu diria que dificilmente isso vai ocorrer.
E no exemplo que eu dei, caso você troque o mecanismo de persistência, só vai ter de fazer modificações no Data Mapper, como faria caso estivesse utilizando diretamente DAO.
|
------------------------------------------------------------------
"Think different? I'd be happy if most people would just think..."
http://www.yaw.com.br
http://twitter.com/rafanunes
|
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 21/06/2007 18:27:21
|
Rafael Nunes
Moderador
![[Avatar]](/images/avatar/d072677d210ac4c03ba046120f0802ec.png)
Membro desde: 09/10/2003 13:41:06
Mensagens: 2833
Localização: sao bernardo do campo
Offline
|
Fabio Kung wrote:Pessoal, não vamos misturar duas discussões né?
Domain Model x BO + DTO é uma coisa.
ActiveRecord (pessoa.save()) x DataMapper (dao.save(pessoa) / repositorio.store(pessoa)) é outra!
Na verdade, ambas foram levantadas no post inicial:
ronildobraga wrote: Mas eu acho que isso nao vem ao caso, o que importa é que uma Pessoa tem que possuir um repositorio e a Pessoa deve ser responsavel pela acoes de persistir um objeto do tipo pessoa ! correto ?
|
------------------------------------------------------------------
"Think different? I'd be happy if most people would just think..."
http://www.yaw.com.br
http://twitter.com/rafanunes
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 21/06/2007 18:27:54
|
fabio.patricio
Forum Spammer
Membro desde: 04/01/2004 02:51:33
Mensagens: 1512
Localização: Porto Alegre - RS
Offline
|
ronildobraga wrote:Eu so me pergunto como ficaria isso mapeado no hibernate, eu teria um Pessoa.hbm.xml referenciando o objeto de dominio e nao mais a um VO ?
Isso mesmo.
]['s
|
Fabio Patricio
http://blog.wansoft.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 21/06/2007 18:28:46
|
felipec
Debugger
Membro desde: 05/04/2007 20:42:19
Mensagens: 67
Offline
|
ronildobraga wrote:
felipec wrote:
Nós não estamos usando mais VO nem BO. Estamos usando um objeto de domínio para cumprir o papel do VO e do BO.
Entendi, obrigado por corrigir.
Eu so me pergunto como ficaria isso mapeado no hibernate, eu teria um Pessoa.hbm.xml referenciando o objeto de dominio e nao mais a um VO ?
Exato!
mas pra melhorar a frase.. "referenciando o objeto de dominio e nao mais um objeto anêmico.."
Porque ja vi muito sistema com objetos anêmicos usarem VOs (nesse caso, o hbm.xml mapeava o objeto anemico e não o VO)
Acho que você entendeu..
|
loogica: http://www.loogica.net/wordpress |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 21/06/2007 21:51:37
|
sergiotaborda
Forum Spammer
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3160
Offline
|
Rafael Nunes wrote: (...)
E particularmente, já ouvi bastante esta questão de 'e se eu trocar de banco', 'e se eu trocar de mecanismo de persistência', 'e se eu trocar o SO do meu servidor'), mas na prática nunca vi e nem ouvi falar disso, (...)
Em termos de aplicações prontas isso é muito verdade. Mas, existe a necessidade de independencia por dois motivos ortogonais a esses.
1) Testabilidade. Ao fazer testes não quero usar o banco. Quero usar uma lista predefenida de valores que usarei nos meus testes. Ai eu substitui o meu DataBaseDAO por um TestDAO (que herda de InMemoryDAO) devidamente inicializado.
2) Vida util. O sistema tem maior vida util quanto mais o seu dominio não depender de tecnologia. Se todas as logicas escritas em Clipper ou COBOL podessem simplesmente ser reaproveitadas mudando apenas o SO, ou o Banco ou a interface gráfica essas linguagens ainda estariam dando cartas. Em Java se mudar o SO vc muda a JVM, se mudar o banco vc muda o DAO, etc.. A sua logica de dominio permanece.
Outra coisa que pode acontecer é mudar a versão do banco , por exemplo, e vc quiser usar funcionalidades novas. Ai vc cria um novo DAO que funciona para essa versão mas não para as anteriores. E assim vai.
Se vc pensa que a vida util do seu programa é menos de 5 anos, então realmente, estas considerações são meio sem sentido e vc acaba criando uma aplicação que dura 5 anos por vicios no seu design. A minha opinião é que a vida util não deve depender dessas coisas se for possivel não depender.
|
Criando sua própria API de Validação
Blog do MiddleHeaven |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 21/06/2007 22:15:11
|
sergiotaborda
Forum Spammer
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3160
Offline
|
ronildobraga wrote:
1)Eu entendo que o objeto de dominio seja a Pessoa, se colocarmos a funcao salvar dentro do repositio e a funcao salvar necessitar de logica, a logica ficaria fora do dominio, a nao ser que o objeto de dominio seja composto por Pessoa + Repositorio, e por isso eu usei composição pois uma pessoa contem um repositorio.
O dominio é constituido de 3 "seres" : Entidades , Objetos de Valor (Value Objects , aka VO , mas não é a mesma coisa que DTO) e Serviços.
Entidades é tudo o que tem identidade (chave).
Objetos de Valor são classes auxiliares que agrupam muitos campos, como endereço, por exemplo
Serviços é aquilo que manipula as entidades para atingir um objectivo no dominio.
CRUD é um tipo de serviço com 2 operações que serve para alterar o universo de instancias de entidades e/ou objetos de valor. Mas um sistema real tem mais doque isso. Imagine a classica transação bancária. Vc tem conta (entidade) e dinheiro (objeto de valor) e quer fazer uma trasnferencia (entidade) . Vc cria um serviço que dada duas contas e um valor, cria uma transferencia. Poderiamos dizer que isto é uma operação CRUD especial , mas é mais do que isso, porque o lançamento da transação é um evento que provoca um monte de outras coisas.
Portanto, se a "função salvar transação" precisa de uma logica suplementar antes de persistir a trnasação, isso fica dentro do Serviço.
Atualizando o seu modelo teriamos
Poderiamos argumentar que o serviço não deveria receber entidades, mas isso é outra conversa que não interessa agora.
Quanto a fazer uma classe Repository com métodos estáticos e genericos:
|
Criando sua própria API de Validação
Blog do MiddleHeaven |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 22/06/2007 00:21:15
|
ronildobraga
JavaEvangelist
Membro desde: 29/03/2006 10:06:51
Mensagens: 433
Localização: sao paulo - sp
Offline
|
sergiotaborda wrote:
Portanto, se a "função salvar transação" precisa de uma logica suplementar antes de persistir a trnasação, isso fica dentro do Serviço.
Poderiamos argumentar que o serviço não deveria receber entidades, mas isso é outra conversa que não interessa agora.
Eu acho que vc fragmentou a objeto de dominio novamente, o seu servico esta se comportando como uma classe de negocio, vc so mudou de nome.
Lendo uma parte do artigo novamente eu frizo o seguinte:
Um modelo rico traduz o mundo real para software da maneira mais próxima possível, ao utilizar classes de dados separadas das classes de lógica esta vantagem é simplesmente jogada fora. No mundo real não existe lógica de um lado e dados de outro, ambos combinados forma um conceito.
Ainda podemos analizar a seguinte imagem
Aqui nos vemos claramente que o Servlet nao tem acesso ao repositorio, se vc criar essa classe de servico, ela sera dependente dos objetos de valor e das entidades, e o servlet tera novamente que popular um objeto(VO) e depois acessar a logica de negocio(BO) do objeto em outro objeto
Eu ainda frizo mais uma parte do artigo:
Num modelo anêmico existem objetos que parecem modelar a realidade, como os VOs, mas na verdade não utilizam a característica básica de objetos que é manter dados e comportamento num mesmo componente: o tão falado objeto!
Observacoes:
Eu nao quero ficar defendendo o artigo, pois acho ele confuso e sem exemplos, mas prestando mmmuuuiitta atenção acho que ele esclarece tudo.
Agora uma coisa que eu nao faço é ficar indicando livros, mandar ler denovo o artigo, tenha mais aulas de OO, leia tudo denovo ou coisas do genero, eu acho que citar partes importantes para tentar esclarecer um assunto nao tem nada de errado, e depois quem estiver lendo esses posts e quiser conhecer como tudo funcione ae sim acho que esta na hora de comprar um livro, ter aulas e etc.
|
Ronildo da Rocha Braga Jr.
Programador, nada mais.
blog: http://www.iprogramming.blogspot.com/ |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 22/06/2007 01:39:53
|
GutomCosta
Thread.start()
![[Avatar]](/images/avatar/f7e4dd6300aa79c1ba9425a76dcf26f5.jpg)
Membro desde: 08/08/2005 20:20:59
Mensagens: 32
Localização: Rio de Janeiro
Offline
|
ronildobraga
Eu acho que vc fragmentou a objeto de dominio novamente, o seu servico esta se comportando como uma classe de negocio, vc so mudou de nome.
Lendo uma parte do artigo novamente eu frizo o seguinte:
Um modelo rico traduz o mundo real para software da maneira mais próxima possível, ao utilizar classes de dados separadas das classes de lógica esta vantagem é simplesmente jogada fora. No mundo real não existe lógica de um lado e dados de outro, ambos combinados forma um conceito.
Na verdade Ronildo, o que o Sergio tentou explicar é que os objetos de domínio necessitam de alguém para coordenar a execução de algumas tarefas.
Para isto faz se necessário um Service.
Imagine o exemplo da transação bancária.
Um objeto Conta, representa a instancia de uma Conta em um banco. Onde ficaria o Serviço de transferência entre 2 contas ?
Em um Service.
Ele vai instanciar as 2 contas e passar o valor de uma pra outra.
Observe que não estamos colocando responsabilidades referentes ao objeto Conta no Service. Ele apenas organiza os passos da execução e delega as responsabilidades para os objetos de domínios.
|
Luiz Costa
www.sagadoprogramador.com.br |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 22/06/2007 01:44:46
|
pcalcado
Moderador
![[Avatar]](/images/avatar/110eec23201d80e40d0c4a48954e2ff5.jpg)
Membro desde: 08/03/2004 17:19:35
Mensagens: 5169
Localização: Sydney - Australia
Offline
|
GutomCosta wrote:
Para isto faz se necessário um Service.
Imagine o exemplo da transação bancária.
Um objeto Conta, representa a instancia de uma Conta em um banco. Onde ficaria o Serviço de transferência entre 2 contas ?
Em um Service.
Ele vai instanciar as 2 contas e passar o valor de uma pra outra.
Observe que não estamos colocando responsabilidades referentes ao objeto Conta no Service. Ele apenas organiza os passos da execução e delega as responsabilidades para os objetos de domínios.
Não entendi direito. O Service neste caso poderia normalment eapenas estimular os objetos, ou seja em vez de:
podemos ter:
|
Phillip Calçado "Shoes"
http://fragmental.tw/
http://blog.fragmental.com.br/
"It is unfortunate that much of what is called 'object-oriented programming today is simply old style programming with fancier constructs." - Alan Kay |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 22/06/2007 03:22:00
|
sergiotaborda
Forum Spammer
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3160
Offline
|
ronildobraga wrote:
sergiotaborda wrote:
Portanto, se a "função salvar transação" precisa de uma logica suplementar antes de persistir a trnasação, isso fica dentro do Serviço.
Poderiamos argumentar que o serviço não deveria receber entidades, mas isso é outra conversa que não interessa agora.
Eu acho que vc fragmentou a objeto de dominio novamente, o seu servico esta se comportando como uma classe de negocio, vc so mudou de nome.
.
Como o GutomCosta já elucidou não foi isso que eu fiz.
Vc precisa de um terceiro "ser" que manipula os objetos do dominio. Porquê?
Imagine um banco verdadeiro no tempo em que não havia computadores.
Contas eram apenas livros e transferencias eram apenas numeros escritos nesses livros. Se as contas eram livros (objectos inanimados) e transferencias era a escrita de numeros quem escrevia os numeros nos livros ? O escriturário. Ele prestava um serviço importante. Ele tinha que garantir que eram colocados os numeros certos nas contas certas e que a operação era atómica (ou o dinheiro era transferido ou não era. sem mais hipoteses) Quando a operação não era atomica ou as contas não eram as que deveriam acontecia um erro.
Em software. Conta é um entidade, o dinheiro é um valor e o responsável por manipular tudo isto é o serviço. Repare que serviço é ainda da camada de dominio. Ele é o cara que entende o que ha a ser feito, e sabe como fazer. No softtware o serviço é responsável por iniciar uma transação (aqui transação JTA) alterar os valores nas contas e fazer o commit. Repare que esta operação não pode ser responsabilidade da conta porque a conta não sabe o que uma transacção entre contas é ( da mesma forma que um livro não sabe o que um escriturário é).
Mas tem mais detalhes ... na realidade uma transacção bancária não é uma operação entre contas é :
1) verificação de saldo disponivel
2) verificação de limite
3) o lançamento atómico de dois movimentos pareados (partidas obradas) um numa e um noutra.
Que em codigo seria mais ou menso assim
A aplicação (a camada de aplicação) chamará o serviço passando os parametros necessários e nunca verá a logica do dominio. Ou seja, o servlet passa a responsabilidade ao serviço (da mesma forma que o atendente do balcão passava ao escriturário)
A "logica de negocio" está na realidade distribuida entre os objectos do dominio , cada uma coma a sua responsabilidade e não mais do que essa.
É preciso deixar claro que o Serviço não é apenas uma mera fachada, ele é o cara que o resto do mundo vê (é o atendente no balcão)
Objetos como Transferencia , MovimentoConta tb existem e é necessário ter um historio deles. Eles são entidades, possuem dados , estado, mas possuem tb tomadas de decisão. Por outro lado, eles existem porque ha que separar a responsabilidade dentro das proprias entidades do dominio.
Conta é apenas um agrupador, o saldo é alterado pelos movimentos de conta , que forma o extrato da conta e portanto têm datas associadas a eles. E cada movimento na sua conta causa um movimento numa outra conta de alguém (partida-dobrada). Se continuar esmiuçando o problema encontrará muito mais entidades necessárias. Se pensar en outros dominios - controle de estoque , por exemplo - verá que algumas entidades se repetem, mas têm papeis diferentes. E tudo isso é a complexidade do dominio que a DDD visa simplificar ao abusar das capacidades oferecidas pela OO.
---
Quanto ao ActiveRecord. Muito simples: na prática não funciona. A razão é simples: quebra de responsabilidade. Os livros não se guardam a si mesmos nas estantes : os objetos de dominio tb não se devem guardar a si mesmos.
Se tentar usar ActiveRecord de uma forma mais gerenciável ,como vc fez, delegando ao repositorio dentro de pessoa, vai acabar com um monte de cdogio repetido, desnecessário, pois chamar o repositorio directamente dá no mesmo e na prática tem mais vantagem (como dilimitar melhor o controlo o commit e o roolbak da persitencia, etc...)
O ActiveRecord é um padrão mencionado em muitos lugares e tem o seu lugar ao sol em determinados usos (DataSet é um exemplo). Mas refere-se a record (registro) e em DDD uma entidade não é vista como um registro porque a persitência é abstraida e portanto existe uma incompatibilidade natural entre ActiveRecord e DDD.
|
Criando sua própria API de Validação
Blog do MiddleHeaven |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 22/06/2007 05:37:11
|
Daniel Quirino Oliveira
Moderador
![[Avatar]](/images/avatar/846c260d715e5b854ffad5f70a516c88.png)
Membro desde: 23/03/2003 23:57:34
Mensagens: 3280
Localização: Awawawawa (Araraquara) - SP
Offline
|
sergiotaborda wrote:
O ActiveRecord é um padrão mencionado em muitos lugares e tem o seu lugar ao sol em determinados usos (DataSet é um exemplo). Mas refere-se a record (registro) e em DDD uma entidade não é vista como um registro porque a persitência é abstraida e portanto existe uma incompatibilidade natural entre ActiveRecord e DDD.
Huh?!
Dá para explicar isso? Aliás, você realmente entendeu o que você acabou de escrever ou você acredita de fato nisso que você falou?
|
Daniel Quirino Oliveira |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 22/06/2007 05:58:48
|
eliziario
JavaChild
![[Avatar]](/images/avatar/801a089759389ea9fa5f77ecc339f4be.jpg)
Membro desde: 13/04/2006 20:14:50
Mensagens: 136
Localização: Rio de Janeiro / Teresópolis
Offline
|
sergiotaborda wrote:
ronildobraga wrote:
sergiotaborda wrote:
Portanto, se a "função salvar transação" precisa de uma logica suplementar antes de persistir a trnasação, isso fica dentro do Serviço.
Poderiamos argumentar que o serviço não deveria receber entidades, mas isso é outra conversa que não interessa agora.
Eu acho que vc fragmentou a objeto de dominio novamente, o seu servico esta se comportando como uma classe de negocio, vc so mudou de nome.
.
Como o GutomCosta já elucidou não foi isso que eu fiz.
Vc precisa de um terceiro "ser" que manipula os objetos do dominio. Porquê?
Imagine um banco verdadeiro no tempo em que não havia computadores.
Contas eram apenas livros e transferencias eram apenas numeros escritos nesses livros. Se as contas eram livros (objectos inanimados) e transferencias era a escrita de numeros quem escrevia os numeros nos livros ? O escriturário. Ele prestava um serviço importante. Ele tinha que garantir que eram colocados os numeros certos nas contas certas e que a operação era atómica (ou o dinheiro era transferido ou não era. sem mais hipoteses) Quando a operação não era atomica ou as contas não eram as que deveriam acontecia um erro.
Em software. Conta é um entidade, o dinheiro é um valor e o responsável por manipular tudo isto é o serviço. Repare que serviço é ainda da camada de dominio. Ele é o cara que entende o que ha a ser feito, e sabe como fazer. No softtware o serviço é responsável por iniciar uma transação (aqui transação JTA) alterar os valores nas contas e fazer o commit. Repare que esta operação não pode ser responsabilidade da conta porque a conta não sabe o que uma transacção entre contas é ( da mesma forma que um livro não sabe o que um escriturário é).
Mas tem mais detalhes ... na realidade uma transacção bancária não é uma operação entre contas é :
1) verificação de saldo disponivel
2) verificação de limite
3) o lançamento atómico de dois movimentos pareados (partidas obradas) um numa e um noutra.
Que em codigo seria mais ou menso assim
A aplicação (a camada de aplicação) chamará o serviço passando os parametros necessários e nunca verá a logica do dominio. Ou seja, o servlet passa a responsabilidade ao serviço (da mesma forma que o atendente do balcão passava ao escriturário)
A "logica de negocio" está na realidade distribuida entre os objectos do dominio , cada uma coma a sua responsabilidade e não mais do que essa.
É preciso deixar claro que o Serviço não é apenas uma mera fachada, ele é o cara que o resto do mundo vê (é o atendente no balcão)
Objetos como Transferencia , MovimentoConta tb existem e é necessário ter um historio deles. Eles são entidades, possuem dados , estado, mas possuem tb tomadas de decisão. Por outro lado, eles existem porque ha que separar a responsabilidade dentro das proprias entidades do dominio.
Conta é apenas um agrupador, o saldo é alterado pelos movimentos de conta , que forma o extrato da conta e portanto têm datas associadas a eles. E cada movimento na sua conta causa um movimento numa outra conta de alguém (partida-dobrada). Se continuar esmiuçando o problema encontrará muito mais entidades necessárias. Se pensar en outros dominios - controle de estoque , por exemplo - verá que algumas entidades se repetem, mas têm papeis diferentes. E tudo isso é a complexidade do dominio que a DDD visa simplificar ao abusar das capacidades oferecidas pela OO.
---
Quanto ao ActiveRecord. Muito simples: na prática não funciona. A razão é simples: quebra de responsabilidade. Os livros não se guardam a si mesmos nas estantes : os objetos de dominio tb não se devem guardar a si mesmos.
Se tentar usar ActiveRecord de uma forma mais gerenciável ,como vc fez, delegando ao repositorio dentro de pessoa, vai acabar com um monte de cdogio repetido, desnecessário, pois chamar o repositorio directamente dá no mesmo e na prática tem mais vantagem (como dilimitar melhor o controlo o commit e o roolbak da persitencia, etc...)
O ActiveRecord é um padrão mencionado em muitos lugares e tem o seu lugar ao sol em determinados usos (DataSet é um exemplo). Mas refere-se a record (registro) e em DDD uma entidade não é vista como um registro porque a persitência é abstraida e portanto existe uma incompatibilidade natural entre ActiveRecord e DDD.
É preciso tomar muito cuidado com analogias, justamente para evitar erros assim. Um modelo OO é justamente isso, um *modelo* do mundo real com uma finalidade específica e não uma representação fiel. E uma aplicação é um modelo da realidade da mesma maneira que um mapa é um modelo da superfície terrestre. Em um mapa países diferentes são pintados em cores diferentes, porque a eficiência do mapa enquanto modelo da realidade é função direta do quanto ele atende o requisito original (identificar claramente fronteiras entre países), mesmo assim, no mundo real, não conheci ainda nenhum país roxo. Da mesma maneira, em uma aplicação Orientada a Objeto, as atribuições de responsabilidades e os papéis exercidos por cada classe não visam a uma "cópia" do mundo real, mas à obediência à uma série de princípios fundamentais que tem finalidades específicas muito concretas de engenharia. Então, pode ser ridículo no mundo real que uma conta corrente "credite-se um DOC", mas pode fazer todo o sentido do mundo isso (conta::recebe_doc) em uma aplicação OO, uma vez que Conta é o Information Expert definitivo quando se trata de receber um DOC. De saída, eu ganho em coesão, e também diminuo o acoplamento, o que não é o caso do seu código, coisa que podemos comprovar facilmente ao ver que seria muito difícil escrever Unit Tests para seu exemplo. (Aliás, isso é outra vantagem de TDD, a dificuldade em escrever testes é sempre um sinal de que nosso design poderia ser melhorado).
Outro ponto é que você confunde Serviço com Facade. Embora possam parecer coisas similares, não são. Um Facade expõe um interface simplificada para um subsistema complexo, mas ainda expõe operações em termos de objetos nativos de uma aplicação (por exemplo, se eu faço um Facade para JavaMail, eu tenho uma interface com parâmetros e retornos que ainda são tipos pertencentes ao namespace original de java mail). Já um serviço expõe uma operação de um processo de negócios desacoplando as duas pontas. Por exemplo, se eu tenho um serviço de consulta de crédito, a interface desse serviço deverá ser genérica o suficiente para poder ser acessada por qualquer cliente que tenha acesso apenas a definição do meu serviço, sem a necessidade de ter conhecimento da estrutura interna da minha aplicação. Em outros termos, eu não preciso importar um jar do correio para acessar o serviço de CEP. Mas no seu exemplo, nem mesmo Facade o seu objeto transferência consegue ser, ele é apenas um método disfarçado de objeto, tire o construtor e o método execute do seu objeto Transferência e coloque um método estático no lugar e não vai ter diferença alguma entre as duas versões, o que demonstra de maneira inequívoca o caráter procedural do seu modelo.
Não vou nem comentar ainda a mistura de código de transação com código de negócios. Também é lamentável que em pleno 2007 ainda tenha gente que use controle de transação de maneira programática e não declarativa, isso realmente me dá muito desgosto.
Sinceramente, acho que você deveria ler o livro do Evans, e o Object Design da Wirfs-Brock. Depois de ler os dois, leia Refactorings do Fowler pra consertar esse seu código aí em cima.
Cordialmente,
Marcos Eliziário
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 22/06/2007 12:10:25
|
ronildobraga
JavaEvangelist
Membro desde: 29/03/2006 10:06:51
Mensagens: 433
Localização: sao paulo - sp
Offline
|
Eu recebi uma mensagem privada do Phillip e peço desculpas publicamente pela mensagem se referindo a ele. Eu e o Phillip nao somos amigos e nao nos conhecemos e por isso nao tenho direito de fazer qualquer comentario relacionado a ele.
Com relação as criticas do artigo, eu espero que ele possa possa receber elas de boa vontade.
Eu acho confuso pelos motivos:
1) Ele nao possui exemplos e peço que observe o texto abaixo, palavras do proprio Martin Fowler em seu artigo sobre IOC
Para ajudar a tornar isso tudo mais concreto, eu usarei um exemplo funcional. Como todos os meus exemplos, este é um daqueles exemplos super-simples; pequeno o bastante para ser irreal, mas o suficiente, espero, para que se possa visualizar o que está ocorrendo sem cair na complexidade de um exemplo real
2) O assunto do artigo esta fragmentado em dois artigos, se vcs perceberem no começo do post eu adicionei os dois artigos.
3) A conclusão nao da uma solução, a conclusao abordou que o problema do modelo anemico ocorreu devido ao EJB 2, e isso foi devido a pessoas nao conhecerem a tecnologia.
4) Peço que olhe o artigo do Martin Fowler retratando o mecanismo de IOC, vc verá os seguintes topicos: Componentes e Serviços, Um Exemplo Simples, Inversão de Controle, Decidindo qual opção usar, Mais algumas questões, Pensamentos Conclusivos, Revisões Significantes.
Espero que tenham entendido que nao tenho nada pessoal contra o Phillip, pois seus artigos é o motivo da discussão desse e demais posts, porem so acho que os artigos podem ser revisados, assim como todo bom Editor faz.
Se a comunidade inteira entendeu claramente os artigos sem qualquer duvida, peço que ignorem esse post e nao facam comentarios
|
Ronildo da Rocha Braga Jr.
Programador, nada mais.
blog: http://www.iprogramming.blogspot.com/ |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 22/06/2007 12:16:40
|
J2Alex
JavaEvangelist
![[Avatar]](/images/avatar/f4be00279ee2e0a53eafdaa94a151e2c.jpg)
Membro desde: 18/01/2003 08:14:41
Mensagens: 341
Localização: São José dos Campos
Offline
|
sergiotaborda,
O que você acha que há de errado na seguinte abordagem:
Eu considero isso bem intuitivo e funcional...
|
Alexandre ( J2Alex )
Desenvolvedor Java EE
ITA (Instituto Tecnológico de Aeronáutica)
Sun Certified Programmer for the Java 2 Platform, Standard Edition 5.0
Não temeis pelos dias que virão - tens a espada e tens as honras e um coração gentil. |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 22/06/2007 12:21:16
|
sergiotaborda
Forum Spammer
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
Membro desde: 22/03/2005 20:57:48
Mensagens: 3160
Offline
|
eliziario wrote:
(...)mesmo assim, no mundo real, não conheci ainda nenhum país roxo. Da mesma maneira, em uma aplicação Orientada a Objeto, as atribuições de responsabilidades e os papéis exercidos por cada classe não visam a uma "cópia" do mundo real, mas à obediência à uma série de princípios fundamentais que tem finalidades específicas muito concretas de engenharia.
Se bem entendo vc está dizendo que Orientação a Objetos não visa ser uma copia do mundo real. É apenas uma tecnologia para satisfazer necessidades em informática.
Eu concordaria consigo de estivessemos falando de classes de alguma biblioteca ou classes de infraestrutura. Não concordo se estivermos falando de classes de dominio.
Se nem as classes de dominio têm que traduzir o mundo real, então nem são necessárias em primeiro lugar. Usemos TO e pronto.
Então, pode ser ridículo no mundo real que uma conta corrente "credite-se um DOC", mas pode fazer todo o sentido do mundo isso (conta::recebe_doc) em uma aplicação OO, uma vez que Conta é o Information Expert definitivo quando se trata de receber um DOC.
Teoricamente isso poderia ser verdade. Mas num sistema real não é assim. Não ha vantagem nenhuma em deixar a conta ser um information expert quando na realidade ela não o é. A conta é apenas um marcador, uma referencia para vários processos dentro do sistema. Ela não contem nenhuma lógica de processo, ela transporta atributos para os processos tomarem decisões.
De saída, eu ganho em coesão, e também diminuo o acoplamento,
Mas imprenga "Conta" com um monte logicas. E quando houver uma alteração a manutenção é dificil.
o que não é o caso do seu código, coisa que podemos comprovar facilmente ao ver que seria muito difícil escrever Unit Tests para seu exemplo.
Cara, é uma exemplo rápido, num contexto de um topico de um forum.... não vai querer que eu perca meio dia escrevendo um codigo testável , funcional, etc, etc.. só para dar um exemplo. Quem souber programar não terá problemas em criar um codigo verdadeiro, funcional, testável, etc etc... o dilema no topico é o que é DDD , qual a sua vantagem/diferença em relação a DTO+BO e não TDD.
Se TDD o procupa neste contexto, sinta-se à vontade de apresentar um exemplo de DDD devidamente programado, que funcione , e seja testável.
Outro ponto é que você confunde Serviço com Facade. Embora possam parecer coisas similares, não são. Um Facade expõe um interface simplificada para um subsistema complexo, mas ainda expõe operações em termos de objetos nativos de uma aplicação (por exemplo, se eu faço um Facade para JavaMail, eu tenho uma interface com parâmetros e retornos que ainda são tipos pertencentes ao namespace original de java mail). Já um serviço expõe uma operação de um processo de negócios desacoplando as duas pontas.
Todos temos problemas... é uma maravilha como neste forum todo o mundo gosta de apontar os problemas dos outros. Vc também tem problemas. Vc não leu o topico inteiro. Se tivesse lido iria ver que escrevi:
sergiotaborda wrote:
Poderiamos argumentar que o serviço não deveria receber entidades, mas isso é outra conversa que não interessa agora.
Eu sei muito bem a diferença entre Façade e Serviço. Isso não é um problema para mim, e pelo visto para si tb não. Só que eu não quiz poluir a discussão com esse detalhe. Eu sei que ao fazer isso iriam dizer que afinal estaria usando objetos que não são do dominio (aka TO) para passar a informação , e voltariamos ao ponto inicial da conversa.
Como o objetivo é entender DDD e no caso, explicar que DDD incorpora a noção de serviço , além de entidade de objeto de valor.
Mas já que vc levantou a lebre .... DDD não vive isolado do mundo, e não é a palavra final em desenvolvimento de software. Para que DDD funcione, ou seja, para que haja um foco efetivo no dominio, tem que existir um infraestrutura que lhe dê suporte. Por exemplo, é chato conectar framewroks web com DDD sem alguém no meio que traduza os requests em chamadas ao serviço do dominio. A camada de aplicação é necessária mesmo com DDD. E é por isso que DDD é muita parra e pouca uva. O assunto era explicar como evitar TO e vc simplesmente acaba de mostrar que DDD não evita TO, aliás necessita deles para serem passados como parametros dos serviços.
Lamento Ronildo, eu não queria desapontá-lo antes do tempo, mas o eliziario não quiz brincar do mesmo jogo, então aqui fica a verdade. DDD não evita TO.
Não vou nem comentar ainda a mistura de código de transação com código de negócios. Também é lamentável que em pleno 2007 ainda tenha gente que use controle de transação de maneira programática e não declarativa, isso realmente me dá muito desgosto.
A mim tb me dá desgosto que em pleno 2007 existam pessoas que não sabem ler - anafalbetos funcionais - e ficam fazendo comentários fora de contexto. A mim tb me dá desgosto que em pleno 2007 existam pessoas que não sabem distinguir didática de técnica. E eu poderia lamentar profundamente a existência destas pessoas, não fosse a existencia de outras que são inteligentes o suficiente para não colocar o carro na frente dos bois. É vida é f#$@ por causa dos primeiro, mas vale a pena por causa dos segundos, tal e qual este forum.
Sinceramente, acho que você deveria ler o livro do Evans, e o Object Design da Wirfs-Brock. Depois de ler os dois, leia Refactorings do Fowler pra consertar esse seu código aí em cima.
Sinceramente acho que a sua opinião é válida e correta, mas fora de contexto. Os seus destaques quanto à incorreta implementação do codigo são absurdos porque estamos num forum e não numa empresa discutindo a melhor implementação. Eles são até válidos , mas vc poderia simplesmente corrigi-los ou indicar os problemas , entendendo que é um exemplo de um forum, e que não eu não sou obrigado a escrever codigo profissional aqui. Ainda para mais com tantos profissionais que sabem escrever codigo tão melhor e dar exemplos tão melhores....
Moral da historia, vc deve primeiro ler o topico inteiro para não assumir coisas demais. Depois não deve assumir que o codigo escrito aqui como exemplo é um codigo funcional e depois não deveria assumir que eu não li os livros que vc leu. Se isto continua vou ter que escrever uma assinatura com todos os livros que já li na vida... e por ultimo, vc deveria ser mais tolerante.
quanto às transações: se vc usar um container e transações declarativas, as responsabilidade da transacção sai do serviço. Por outro lado, existem ocasiões em que a transação é um conceito mais amplo que JTA , ou foge ao seu escopro (como transações aninhadas) e tem que ser controlado pelo serviço - da mesma forma que um escriturário lida com problemas como falta de tinta na caneta... Mas tudo bem, eu entendi o seu recado: 'cuidado com analogias". Ignore-se então a chamada a commit e roolbak.
Seria muito bom para quem está lendo este topico que vc , ou alguem, desse um exemplo real de uso de DDD num sistema que tenham ai funcionando (com os devidos testes de unidades e tudo o mais) para que os novatos não caiam no erro de chamar a transação na mão .... (como fizeram na javamagazine deste mês ... )
|
Criando sua própria API de Validação
Blog do MiddleHeaven |
|
|
 |
|
|
|
|
|