Domain na Camada de Apresentação (Preciosismo?)

Tenho acompanhado as discussoes sobre “domains” e para levar um dominio ate a camada de apresentação. Voces acham que é interessante levar um objeto de dominio ate a camada de apresentacao, pq alguem pode chamar um metodo de negocio dele?

Num JSF voces mapeam o Managed Bean com os mesmos campos do domain?

Vlw!

[quote=rob1980a]Tenho acompanhado as discussoes sobre “domains” e para levar um dominio ate a camada de apresentação. Voces acham que é interessante levar um objeto de dominio ate a camada de apresentacao, pq alguem pode chamar um metodo de negocio dele?
[/quote]

Por isso que as entidades de dominio não podem ter métodos que altera o seu estado ( aka ActiveRecord)

Das duas uma:

  1. Suas entidades são ricas , tão ricas que contêm métodos que alteram o estado do sistema como um todo.
    Um chamada no momento errado a esses métodos e “Bum!”. Neste caso não é bom passar suas entidades para lado nenhum. Crie outros objetos com o mesmo estado e sem métodos ( aka TO) ( trabalheira)
  2. Suas entidades são pobre ou ricas, mas não tão ricas que contenham métodos que explodem seu sistema.
    Neste caso um chamada aos método altera no máximo a propria entidade e suas filhas. mas como não ha um método “save” essas alterações não causam efeito no estado do sistema como um todo. Aqui não precisa de TO, pode usar os objetos de entidade normalmente.

É uma violação do isolamento do dominio ? Pode até ser que seja, mas é um trade-off. É melhor isso que criar TO iguazinhos às entidades só para que eles viajem nas camadas.

[quote=sergiotaborda][quote=rob1980a]Tenho acompanhado as discussoes sobre “domains” e para levar um dominio ate a camada de apresentação. Voces acham que é interessante levar um objeto de dominio ate a camada de apresentacao, pq alguem pode chamar um metodo de negocio dele?
[/quote]

Por isso que as entidades de dominio não podem ter métodos que altera o seu estado ( aka ActiveRecord)[/quote]
Pode explicar isso melhor? ActiveRecord por acaso é ruim na sua opinião?

[quote=sergiotaborda]
Das duas uma:

  1. Suas entidades são ricas , tão ricas que contêm métodos que alteram o estado do sistema como um todo.
    Um chamada no momento errado a esses métodos e “Bum!”. Neste caso não é bom passar suas entidades para lado nenhum. Crie outros objetos com o mesmo estado e sem métodos ( aka TO) ( trabalheira)[/quote]
    TO, DTO São para evitar chamadas remotas e não para evitar o problema em questão.

[quote=sergiotaborda]
É uma violação do isolamento do dominio ? Pode até ser que seja, mas é um trade-off. É melhor isso que criar TO iguazinhos às entidades só para que eles viajem nas camadas.[/quote]
O que você acha de usar uma interface apenas com os métodos permitidos? Eu ainda prefiro que a camada de domínio seja ortogonal, mas …

[quote=emerleite][quote=sergiotaborda][quote=rob1980a]Tenho acompanhado as discussoes sobre “domains” e para levar um dominio ate a camada de apresentação. Voces acham que é interessante levar um objeto de dominio ate a camada de apresentacao, pq alguem pode chamar um metodo de negocio dele?
[/quote]

Por isso que as entidades de dominio não podem ter métodos que altera o seu estado ( aka ActiveRecord)[/quote]
Pode explicar isso melhor? ActiveRecord por acaso é ruim na sua opinião?
[/quote]

Padrões não são ruins ou bons, eles são uteis ou danosos em certos cenários.
No cenário em que eu quero utilizar o objeto da entidade como objeto de transporte (TO) eu não quero que isso possa interferir com o estado do sistema. Neste caso ActiveRecord é danoso. Mas qualquer método na entidade que altere o estado do sistema ( do sistema, não da entidade) é danoso neste cenário.

[quote]

Isso é o que eles querem que vc acredite.
O ponto em questão é levar os dados (do dominio) até à camada de apresentação. Isso é inerentemente um problema de transporte. Logo é a própria definição de um objeto de transfrencia de dados, de transporte (TO)

Um caso particular do uso disse é quando fazemos chamadas remotas, mas isso é apenas um caso particular de um padrão mais genérico.

O problema do topico é: devo criar novos objetos que apenas contêm o estado das entidades do dominio para maniuplar em outras camadas, em particular a de apresentação ? Claro que não. Isso é uma trabalheira. Isso é o que se fazia com os TO e os EJB Entity Beans. Então a solução é utilizar os próprios objetos de entidade. Mas se eles são demasiado poderosos podem ferrar o sistema. É só isso.

Suponho que “permitidos” significa “seguros”, "que não provocam efeitos desagradáveis"
Poderia utilizar essa medida. É talvez um melhor trade-off que tudo ou nada. Mas num ambiente livre de métodos periogosos seria irrelevante. Só seria util se vc quiser incluir os métodos perigosos. A pergunta é , portanto: vc gosta de programar perigosamente ? Elimine os métodos perigosos e vc eliminou todos os seus problemas. Inclua-os e arrisque-se a que alguem ferre o seu sistema.

Realmente Sergio na pratica as coisas se complicam um pouco… DDD ta sendo interessante, mas tem problemas como esse que atrapalha (apesar de nao ser problema do DDD).

No JSF vcs mapeiam como no MB?

Alguem mais tem alguma ideia de como usar as classes de dominio na camada de aprentação? Como vcs fazem nos sistemas de vcs?

Também prefiro a utilização de interfaces mais restritivas nos casos onde eu preciso garantir que alguns métodos não sejam invocados.

[quote=rob1980a]Realmente Sergio na pratica as coisas se complicam um pouco… DDD ta sendo interessante, mas tem problemas como esse que atrapalha (apesar de nao ser problema do DDD).
[/quote]

Não entendi onde atrapalha …

Eu não uso JSF ( e antes que alguem pergunte: não uso porque não faço sistemas web) mas em principio
vc não tem que mapear de nenhuma forma especial. No MB vc tem que ter métodos que lhe retornem apenas o que vc precisa.
Se o método tem que fazer algum truque (como encapsular as entidades do dominio numa outra coisa) então que seja. Mas na realidade a coisa vai mais da necessidade das páginas do que do dominio em si. o MB é o seu “tradutor”.

transformar num TO o dominio ou criar uma interface, como voce mesmo disse é uma trabalheira, ou assumir o risco de jogar o dominio pra apresentação

[quote=sergiotaborda]
Eu não uso JSF ( e antes que alguem pergunte: não uso porque não faço sistemas web) mas em principio
vc não tem que mapear de nenhuma forma especial. No MB vc tem que ter métodos que lhe retornem apenas o que vc precisa.
Se o método tem que fazer algum truque (como encapsular as entidades do dominio numa outra coisa) então que seja. Mas na realidade a coisa vai mais da necessidade das páginas do que do dominio em si. o MB é o seu “tradutor”.[/quote]
Imagino que a boa parte dos sistemas os atributos do dominio ficaria diferentes da tela, e pra mapear isso seria complicado. Alguem ja passou por isso?

[quote=rob1980a]
Imagino que a boa parte dos sistemas os atributos do dominio ficaria diferentes da tela, e pra mapear isso seria complicado. Alguem ja passou por isso? [/quote]

Normalmente não. O objeto do dominio é usado directamente na tela.

[quote=sergiotaborda][quote=emerleite]

Isso é o que eles querem que vc acredite.
O ponto em questão é levar os dados (do dominio) até à camada de apresentação. Isso é inerentemente um problema de transporte. Logo é a própria definição de um objeto de transfrencia de dados, de transporte (TO)

Um caso particular do uso disse é quando fazemos chamadas remotas, mas isso é apenas um caso particular de um padrão mais genérico.
[/quote][/quote]

Particular? A Sun, O Fowler e todos os lugares que voce encontrar a descricao, voce vai ver que fala que é para evitar o acumulo de chamadas remotas de granularidade fina:
http://java.sun.com/blueprints/patterns/TransferObject.html
http://www.martinfowler.com/eaaCatalog/dataTransferObject.html

Em que caso usariamos esse padrao mais generico, e onde ha a descricao? nao consigo ver a utilidade de usar DTo/TO sem ser para transferir dados entre TIERS (e nao layers).

[quote=sergiotaborda][quote=emerleite][quote=sergiotaborda][quote=rob1980a]Tenho acompanhado as discussoes sobre “domains” e para levar um dominio ate a camada de apresentação. Voces acham que é interessante levar um objeto de dominio ate a camada de apresentacao, pq alguem pode chamar um metodo de negocio dele?
[/quote]

Por isso que as entidades de dominio não podem ter métodos que altera o seu estado ( aka ActiveRecord)[/quote]
Pode explicar isso melhor? ActiveRecord por acaso é ruim na sua opinião?
[/quote]

Padrões não são ruins ou bons, eles são uteis ou danosos em certos cenários.
No cenário em que eu quero utilizar o objeto da entidade como objeto de transporte (TO) eu não quero que isso possa interferir com o estado do sistema. Neste caso ActiveRecord é danoso. Mas qualquer método na entidade que altere o estado do sistema ( do sistema, não da entidade) é danoso neste cenário.[/quote]
Nesse caso, se você achar realmente necessário, crie uma interface como sugeri anteriormente apenas com os métodos “não-danosos”.

[quote=sergiotaborda]

[quote]

Isso é o que eles querem que vc acredite.[/quote]
Não. Isso é a definição e o propósito do padrão.
http://www.martinfowler.com/eaaCatalog/dataTransferObject.html
http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html
http://java.sun.com/blueprints/patterns/TransferObject.html
http://www.corej2eepatterns.com/Patterns2ndEd/TransferObject.htm

[quote=sergiotaborda]
O ponto em questão é levar os dados (do dominio) até à camada de apresentação. Isso é inerentemente um problema de transporte. Logo é a própria definição de um objeto de transfrencia de dados, de transporte (TO)

Um caso particular do uso disse é quando fazemos chamadas remotas, mas isso é apenas um caso particular de um padrão mais genérico. [/quote]
Sergio, a sua referência é ao seu próprio Blog. Leiamos as fontes originais que citei acima. É possível que você tenha lido o livro Core J2EE Patterns em português, que a tradução é horrível, como 99% dos casos. Na tradução, está escrito camadas, sem fazer diferença entre Layer e Tier. No original em inglês, está escrito Tier e não Layer. Um camarada do trabalho uma vez ficou justificando que estava escrito camadas mas no caso ele também estava lendo em português e sustentando este argumento furado.

[quote=sergiotaborda]
O problema do topico é: devo criar novos objetos que apenas contêm o estado das entidades do dominio para maniuplar em outras camadas, em particular a de apresentação ? Claro que não. Isso é uma trabalheira. Isso é o que se fazia com os TO e os EJB Entity Beans. Então a solução é utilizar os próprios objetos de entidade. Mas se eles são demasiado poderosos podem ferrar o sistema. É só isso. [/quote]
Caso você julgue danoso, crie uma interface apenas com o que poderá ser chamado. Criar uma interface ao invés de duplicar objetos é melhor, IMO.

Sinceramente ainda não entendi esse argumento de programar perigosamente. Poderia exemplificar em código pra ficar mais claro?

[EDITED]O Paulo ainda escreveu na minha frente de tão grande que ficou meu POST :slight_smile: Mas ta valendo[/EDITED]

De qualquer maneira o negócio esta codificado no domínio se sua entidade é rica. Não entendo pq tanto receio de que algum método seja invocado do ManagedBean.

Invocação não significa implementação do domínio… o código continuara na camada adjacente. O que obviamente não seria interessante é o domínio conhecer algo da application, o que não é o caso.

PS: Não estou entrando no mérito de façades pq acho que não é o ponto.

Uma pergunta aos que sugeriram a interface:

Vocês fazem desta maneira para evitar que um método que não deveria ser invocado aconteça na applayer? Se isso é padrão adotado pela equipe (não invocar métodos do domínio pela app), esta implementação (uso de interface para restringir)é para evitar um programador que saia da regra?

Se a resposta da ultima for “sim”, como garantir que este mesmo programador vai inferir uma instancia concreta na interface restrita (pensada pelo arquiteto) ao invéz de atribui-la diretamante a uma referencia da classe?

Juro que não é crítica, é para entender este contexto que voces colocaram mesmo …

Alessandro,

É exatamente isso que você falou. Não tem como garantir nada. Mas no caso da interface, a unica coisa que da pra fazer é alguma ferramenta automatizada de QA que faça uma varredura e garanta que não há uso das classes de domínio. No caso de um retorno de método da camada de aplicação, estaria declarado o retorno como uma interface o que faria com que fosse usado esta (Novamente você tem razão, não da pra garantir).

Essa solução é uma solução posível para algumas Empresas/Pessoas que acreditam ser ruim “vazar” os objetos. Quero deixar claro aqui que eu detesto isso, mas no caso de uma restrição imposta por alguém de não expor os objetos (e acho que você entende o que eu quero dizer), a interface é uma opção melhor do que duplicar os objetos, IMO.

Concordo Emerson, se for para replicar objetos volto para os ActionForms do Struts 1.x e continuo a matar bebês focas :slight_smile:

(ta, a piada dos bebês focas hoje é sem graça, mas em 2004 no GUJ isso fazia sentido… )

Tem uma coisa que eu não entendi: como posso substituir TO por interfaces quando a apresentação e o negócio estão em TIERS diferentes? Até onde eu sei, o cliente recebe um objeto em formato serializável, e pra deserializá-lo, é necessário a definição da classe no lado cliente também.

Supondo que, com interface não dá, existe jeito de se separar a aplicação em TIERS, sem usar TO, mas ao mesmo tempo, concentrar a regra de negócio no lado servidor?

[quote=Leonardo3001]Tem uma coisa que eu não entendi: como posso substituir TO por interfaces quando a apresentação e o negócio estão em TIERS diferentes? Até onde eu sei, o cliente recebe um objeto em formato serializável, e pra deserializá-lo, é necessário a definição da classe no lado cliente também.

Supondo que, com interface não dá, existe jeito de se separar a aplicação em TIERS, sem usar TO, mas ao mesmo tempo, concentrar a regra de negócio no lado servidor?[/quote]
No caso em que a apresentação e o negócio estão em TIERS diferentes você sim usa TOs (DTOs). O ponto em que batemos aqui foi usar DTOs entre LAYERS e não TIERS. Como eu disse anteriormente, se a pessoa aprendeu sobre esse padrão através do livro Core J2EE Patterns em português, possivelmente quando leu a palavra camadas (que no original está TIER), pode ter entendido como LAYER e dai confunde tudo.

@lezinho
Esse negócio da foca realmente era engraçado. Tinha um monte de gente com isso na assinatura do GUJ :smiley: . E tinha também uma mais ou menos assim: “Depois que usei o spring, nunca mais usei struts”. Acho que é mais ou menos isso :smiley: :smiley: :smiley:

Se estamos falando de como a Camada de Apresentação de uma aplicação se comunica com a Camada de Negócios dela realmente qualquer coisa que Não simplesmente passar os objetos é estranho. No caso de uma API se proteger com interfaces e factories é mais do que suficiente, creio.

E esse artigo é ótimo: http://martinfowler.com/bliki/LocalDTO.html:

Ontem a noite quando eu estava postando sobre esse assunto eu aproveitei pra ler esse texto sobre LocalDTO. Realmente explica tudo.