Domain na Camada de Apresentação (Preciosismo?)  XML
Índice dos Fóruns » Arquitetura de Sistemas
Autor Mensagem
pcalcado
Moderador
[Avatar]

Membro desde: 08/03/2004 17:19:35
Mensagens: 5169
Localização: Sydney - Australia
Offline

Gustavo Serafim wrote:
No contexto de CBD, algumas pessoas julgam necessária uma abordagem parecida como a citada por Fowler. Utilizando algo como um DTO ou PO para garantir que o cliente fique desacoplado de uma implementação (por exemplo, da implementação de um subsistema, POJOS com regras de negocio), considerando os DTOs e POs como parte da interface (API).




Gustavo,

Como falei uma APi como a exposta por um componente e serviço requer mais cuidado mas:

1) Ainda assim, principalmente se for um componente instance-based, você não precisa de objetos burros, basta usar interfaces que exibam apenas os métodos relevantes. Para componentes remotos ou type-based você pode facilmente utilizar contratos, e ainda assim objetos burros ou DTO não são necessariamente uma necessidade.

2) O desenvolvimento de um componente é completamente diferente da integração entre duas Camadas de uma aplicação


Gustavo Serafim wrote:
Essa abordagem parece razoável, mas tem um custo que não compensa (citado por Fowler). Principalmente em consultas, não existe muitas complicações em objetos de domínio "vazar..." Mas e na criação de um objeto?

Instanciar um objeto gera acoplamento (GRASP), no caso estaríamos instanciando um objeto de domínio fora da cama de negócio... Eu sei que a camada de apresentação não necessita desse "cuidado", mas essa falta de "coesão" pode gerar outros problemas. Um objeto de domínio representa as regras de negocio, essas regras podem gerar exceções de negócio. Podemos ter regras em construtores e em métodos set..., disparando exceções de negócio (alterações de estados podem gerar validações).


Essas questões são tratadas na camada de negócio, mas no caso de um cadastro? O objeto deve ser instanciado na camada de apresentação? Criando para isso construtores e métodos set... sem regras e outros métodos com as regras para serem utilizados apenas na camada de negócio? Neste caso não é melhor usar um PO, deixando os objetos de domínios só com métodos de negocio?


Isso não é falta de coesao e é acilmente resolvido com uma factory na Camada de Negócios. Você cria um serviço no seu domínio que instancia objetos.




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
[Email] [WWW] [Yahoo!] [MSN]
rob1980a
HelloWorld

Membro desde: 25/06/2007 23:52:18
Mensagens: 20
Localização: BH
Offline

No Managed Bean, eu teria que receber a camada de dominio, e na tela teria os atributos dela no Managed Bean, como eu mapearia isso? Teria duplicidade de atributos!

Gustavo Serafim
Thread.start()
[Avatar]

Membro desde: 04/09/2006 15:33:40
Mensagens: 49
Offline

pcalcado wrote:

Gustavo,

Como falei uma APi como a exposta por um componente e serviço requer mais cuidado mas:

1) Ainda assim, principalmente se for um componente instance-based, você não precisa de objetos burros, basta usar interfaces que exibam apenas os métodos relevantes. Para componentes remotos ou type-based você pode facilmente utilizar contratos, e ainda assim objetos burros ou DTO não são necessariamente uma necessidade.



Phillip,
realmente não é sempre necessário, mas para proteger a implementação de um componente (que no caso fica na camada de negocio), principalmente visando o desacoplamento, precisamos de interfaces bem definidas. Como você já conhece: pré, pós condições, exceções e outras considerações de interfaces bem definidas... ( bject-Oriented Design Using UML - Meilir Page-Jones). Assim, neste caso (componentes), talvez fosse interessante manter os objetos de negocio - que são encapsulados no componente e podemos considerar sua implementação - dentro dos componentes, creio.

pcalcado wrote:

Gustavo,

2) O desenvolvimento de um componente é completamente diferente da integração entre duas Camadas de uma aplicação



Sim eu entendo, mas eu estava falando de componentes de negócio, por isso levantei essa questão. Minha preocupação e com o estado consistente do objeto de negócio (encapsulado dentro do componente). Para manter essa consistência, regras de criação e alteração de estado são necessárias, essas regras disparam exceções de negócio. Então deveriam ser manipulados (construtores e set..) apenas dentro do componente de negócio, eu acredito. Claro que esse formalismo depende do caso.


Segue um artigo do seu bliki

pcalcado wrote:Mais que POJOs, objetos de uma maneira geral devem garantir seu estado. Programar com contratos (DBC - Design by Contract) reforça isto através de algumas regras.


Contudo, trabalhar com interfaces e fabricas pode ser tão trabalhoso quanto usar objetos burros na interface de um componente de negócio. Com essa abordagem, objetos burros para interfaces, não teríamos objetos de negocio na camada de apresentação.
(em qualquer caso alguns desses mecanismos arquiteturais podem ser automatizados)





This message was edited 1 time. Last update was at 02/05/2008 02:52:06


Gustavo S. Sinis
[Email] [WWW]
Gustavo Serafim
Thread.start()
[Avatar]

Membro desde: 04/09/2006 15:33:40
Mensagens: 49
Offline

Um exemplo simples, mas acho que pode contribuir.

Temos um objeto de negócio Funcionário. Ele tem um atributo de instância salário e outro atributo de instância que representa seu cargo. Temos duas regras de negócio: 1 - salário de um funcionário deve ser maior que o salário mínimo para seu cargo; 2 - um funcionário novo deve ganhar menos que a media do seu setor.

Toda vez que alterar o estado do objeto de negócio temos que validar algumas regras para o objeto não ficar inconsistente, disparando exceções se necessário. (MEILIR=PAGE-JONES - Fundamentos do Desenho Orientado a Objeto com UML)

Quando o método setSalario for usado, devemos validar suas regras. O método setSalario vai comparar o valor informado com o valor mínimo do seu cargo, garantindo a regra 1. (GRASP)
Ainda, uma classe Setor deveria ser responsável por criar um Funcionário (GRSP). Para garantir a pré-condição (Regra 2).
Assim não existiriam funcionários com estado inconsistente.



Se escondermos esses métodos com regras em uma interface, possibilitando sua utilização na camada de apresentação, teríamos que criar também outros métodos "burros" para usarmos na camada de apresentação. Não sei se compensa...

This message was edited 3 times. Last update was at 01/05/2008 17:23:54


Gustavo S. Sinis
[Email] [WWW]
pcalcado
Moderador
[Avatar]

Membro desde: 08/03/2004 17:19:35
Mensagens: 5169
Localização: Sydney - Australia
Offline

Gustavo Serafim wrote:
realmente não é sempre necessário, mas para proteger a implementação de um componente (que no caso fica na camada de negocio), principalmente visando o desacoplamento, precisamos de interfaces bem definidas. Como você já conhece: pré, pós condições, exceções e outras considerações de interfaces bem definidas... ( bject-Oriented Design Using UML - Meilir Page-Jones). Assim, neste caso (componentes), talvez fosse interessante manter os objetos de negocio - que são encapsulados no componente e podemos considerar sua implementação - dentro dos componentes, creio.


O que se ganha nisso?

Gustavo Serafim wrote:
Sim eu entendo, mas eu estava falando de componentes de negócio, por isso levantei essa questão. Minha preocupação e com o estado consistente do objeto de negócio (encapsulado dentro do componente). Para manter essa consistência, regras de criação e alteração de estado são necessárias, essas regras disparam exceções de negócio. Então deveriam ser manipulados (construtores e set..) apenas dentro do componente de negócio, eu acredito. Claro que esse formalismo depende do caso.


Eu entendi mas não importa se são componentes de infra-estrutura, negócios ou o que for, o design é completamente diferente.

Gustavo Serafim wrote:
Segue um artigo do seu bliki

pcalcado wrote:Mais que POJOs, objetos de uma maneira geral devem garantir seu estado. Programar com contratos (DBC - Design by Contract) reforça isto através de algumas regras.


Contudo, trabalhar com interfaces e fabricas pode ser tão trabalhoso quanto usar objetos burros na interface de um componente de negócio. Com essa abordagem, objetos burros para interfaces, não teríamos objetos de negocio na camada de apresentação.
(em qualquer caso alguns desses mecanismos arquiteturais podem ser automatizados)


Você pode dar um exemplo ou elaborar como criar uma interface pode ser mais trabalhoso que mantêr duas hierarquias paralelas de objetos (mais o devido códio para mapeamento)?


No seu exemplo, basta a interface não contêr o método setSalario, que faria parte da classe que a implementa. Ela teria um getSalario, entretanto. Não entendi seu ponto sobre criar métodos burros, existe uma diferença entre ter métodos burros e ter métodos sem efeito colateral (como um acessor).


Uma coisa interesante é que qualquer coisa nesse sentido é uma alsa segurança*, na verdade é mais um padrão da linguagem em específico.

This message was edited 3 times. Last update was at 01/05/2008 19:17:25


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
[Email] [WWW] [Yahoo!] [MSN]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 616
Offline

Neste seu exemplo Gustavo, o que de mal aconteceria se setSalario fosse acessado na camada de apresentação?

This message was edited 2 times. Last update was at 01/05/2008 22:05:10


... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.ning.com/

[Email] [MSN]
Gustavo Serafim
Thread.start()
[Avatar]

Membro desde: 04/09/2006 15:33:40
Mensagens: 49
Offline

Lezinho wrote:Neste seu exemplo Gustavo, o que de mal aconteceria se setSalario fosse acessado na camada de apresentação?


Regras de negócio seriam executadas fora da camada de negócio, ou seja, exceções de negócio poderiam ser disparadas na camada de apresentação.
Se você não vê problema com isso, então não tem mal nenhum... Acredito que regras de negócio ficam melhor na camada de negócio. Uma abordagem com interfaces ou objetos "burros" controla melhor isso.

This message was edited 1 time. Last update was at 01/05/2008 23:00:44


Gustavo S. Sinis
[Email] [WWW]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 616
Offline

Gustavo wrote: Regras de negócio seriam executadas fora da camada de negócio, ou seja, exceções de negócio poderiam ser disparadas na camada de apresentação.
Se você não vê problema com isso, então não tem mal nenhum... Acredito que regras de negócio ficam melhor na camada de negócio. Uma abordagem com interfaces ou objetos "burros" controla melhor isso.


Qual regra de negócio ocorreria? Receber exceptions e deixa-las "Gracefully" é tarefa desta camada mesmo...

É a opinião de quem vê mal nisso que gostaria de saber Gustavo. O que prejudica no design uma DomainException? Quem mal prático isso poderia acarretar em sua opinião?

This message was edited 2 times. Last update was at 01/05/2008 23:20:36


... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.ning.com/

[Email] [MSN]
Gustavo Serafim
Thread.start()
[Avatar]

Membro desde: 04/09/2006 15:33:40
Mensagens: 49
Offline

pcalcado wrote: O que se ganha nisso?

Phillip, qual parte? "Proteger a implementação" ajuda diminuir o acoplamento. "Manter objetos sempre em estado consistente" ajuda muito quando temos muitas regras complexas. Quando temos muitas trocas de mensagens para cumprir uma regra complexa, podemos inserir erros de lógica de negocio mais facilmente quando os objetos ficam inconsistentes em algum momento.
pcalcado wrote:
Você pode dar um exemplo ou elaborar como criar uma interface pode ser mais trabalhoso que mantêr duas hierarquias paralelas de objetos (mais o devido códio para mapeamento)?

Se você diz que manter uma hierarquia de interfaces e fabricas não é mais trabalhoso, então eu acredito.

Tanto interfaces quanto objetos "burros" protegem a implementação de um componente de negócio, então acredito que as duas abordagem são úteis para componentes de negócio.

This message was edited 5 times. Last update was at 02/05/2008 02:53:10


Gustavo S. Sinis
[Email] [WWW]
Gustavo Serafim
Thread.start()
[Avatar]

Membro desde: 04/09/2006 15:33:40
Mensagens: 49
Offline

Lezinho wrote:
Qual regra de negócio ocorreria? Receber exceptions e deixa-las "Gracefully" é tarefa desta camada mesmo...


Regra 1 - salário de um funcionário deve ser maior que o salário mínimo para seu cargo.


Lezinho wrote:
É a opinião de quem vê mal nisso que gostaria de saber Gustavo. O que prejudica no design uma DomainException? Quem mal prático isso poderia acarretar em sua opinião?


Alessandro, tenho certeza que qualquer justificativa tecnológica ou prática como, por exemplo, Lazy Load você mostraria uma solução elegante. (Para resolver algumas regras de negócio é necessário acessar outros objetos, por isso comentei do Lazy Load)

Na verdade, esse exemplo é muito simples e não vai justificar uma abordagem mais complexa como decomposição em camadas. (LayeringPrinciples) Abordagens como Business layer, CBD e Manter o estado dos objetos consistentes se destinam, na maioria das vezes, a supera limitações humanas, como lidar com grande quantidade de informações ou complexas (regras de negócio complexas ).

Em alguns casos, como subsystem, só é possível justificar a abordagem se pensamos corporativamente e no efeito acumulativo, não em um projeto especifico. Por isso, esta é uma questão de padronização e talvez de reuso.

This message was edited 2 times. Last update was at 02/05/2008 03:33:17


Gustavo S. Sinis
[Email] [WWW]
Gustavo Serafim
Thread.start()
[Avatar]

Membro desde: 04/09/2006 15:33:40
Mensagens: 49
Offline

pcalcado wrote:
Eu entendi mas não importa se são componentes de infra-estrutura, negócios ou o que for, o design é completamente diferente.


Phillip, eu entendi, mas no design de um componente de negócio decidimos como será a interface desses componentes e eles podem expor os objetos de negócios ou não. Esses objetos podem acabar na camada de apresentação dependendo da abordagem, por isso aproveitei para levantar essa questão... Agora falar de componentes só com um chopp...

Gustavo S. Sinis
[Email] [WWW]
Alessandro Lazarotti
Virtual Machine Man
[Avatar]

Membro desde: 21/01/2004 14:12:54
Mensagens: 616
Offline

Gustavo wrote:Regra 1 - salário de um funcionário deve ser maior que o salário mínimo para seu cargo.


Esta regra é contida no domínio. A appLayer é simplesmente notificada do sucesso ou não desta, mas ele não a possui. Sabendo do resultado decorrente da ação do domínio, é natural que a camada de aplicação/apresentação controle o flow e apresente de forma clara para a view o ocorrido, isto esta dentro do seu escopo de execução desta camada.

Gustavo wrote:Na verdade, esse exemplo é muito simples e não vai justificar uma abordagem mais complexa como decomposição em camadas.


Mas é sobre isso mesmo que estou indagando Gustavo, a decomposição de camadas e não ir contra isso. Tal decomposição não implica na independência de camadas em direção bilateral (isto é adjacente -> subjacente e subjacente -> adjacente). Uma camada adjacente conhece elementos da subjacente, o contrário não é verdadeiro.

Um Command conhecer uma DomainException esta neste escopo e não justifica a criação de engenhosidades para contornar tal conhecimento, que não afeta nem modifica o domínio.

... Lezinho
------------------------
twitter: @lazarotti
http://alessandrolazarotti.wordpress.com/
http://jbossbrasil.ning.com/

[Email] [MSN]
Emerson Macedo
Virtual Machine Man
[Avatar]

Membro desde: 01/08/2006 16:55:28
Mensagens: 669
Localização: Rio de Janeiro - RJ
Offline

Já discuti isso (e muito) com o Gustavo pessoalmente nesta semana, então não vou me repetir textualmente.

O ponto que eu acho que a maioria defende é o fato de não fazer BDUF e a filosofia de YAGNI. Não faz muito sentido fazer implementações na base da suposição, como por exemplo: Vou interfaciar usando DTOs, pois estou prevendo acesso remoto.

Muita coisa fica no campo da preferência, mas o que a maioria dos profissionais tem percebido é que simplicidade no design com um mínimo de organização, na maioria dos casos é melhor. Por isso que eu gosto mais da opção de só usar DTOs se eu tiver certeza absoluta do acesso remoto, e mesmo assim, só usaria este para atender a essa interface remota em específico.

Emerson Macedo Leite
PMP - Ping-pong Master Player
CSM - Counter-Strile Manager
http://codificando.com

"Porque, assim como o relâmpago sai do oriente e se mostra até o ocidente, assim será também a vinda do filho do homem." - Mateus 24:27
[Email] [WWW] [Yahoo!] [MSN] [ICQ]
sergiotaborda
Forum Spammer
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3187
Online

Gustavo Serafim wrote:
Lezinho wrote:Neste seu exemplo Gustavo, o que de mal aconteceria se setSalario fosse acessado na camada de apresentação?


Regras de negócio seriam executadas fora da camada de negócio, ou seja, exceções de negócio poderiam ser disparadas na camada de apresentação.


Tecnicamente a execução da regra de negocio está no objeto Funcionário que pertence à camada de negocio.
Ou seja, o método executa no objeto da camada de negocio. logo, independentemente de onde o método é invocado as regras sempre seriam executadas na camada de negocio. As exceções seriam disparads por esses mesmos métodos, logo, seriam disparadas pela camada de negocio. Não a de apresentação.
A camada de apresentação poderia tratar as exeções em forma de apresentação ( mensagens ao usuario): mas isso é normal nessa camada. Ela poderia ainda invocar os métodos do objeto funcionário. Embora isso possa não ser certo não implica que a camada de apresentação tem qualquer conhecimento sobre as regras de negocio.

Por outro lado, o desenho do exemplo de funcionário não contém métodos que alteram o estado do sistema, logo, não ha nenhum perigo em invocar esses métodos de qualquer outra camada.

Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
Gustavo Serafim
Thread.start()
[Avatar]

Membro desde: 04/09/2006 15:33:40
Mensagens: 49
Offline

sergiotaborda wrote:
Por outro lado, o desenho do exemplo de funcionário não contém métodos que alteram o estado do sistema, logo, não ha nenhum perigo em invocar esses métodos de qualquer outra camada.


Alterar um atributo de instância de um objeto de negócio não é alterar o estado do sistema? Se você esta falando de base, esses objetos podem ser gerenciados por um mapeamento objeto relacional como, por exemplo, o Hibernate.

Gustavo S. Sinis
[Email] [WWW]
 
Índice dos Fóruns » Arquitetura de Sistemas
Ir para:   
Powered by JForum 2.1.8 © JForum Team