Arquitetura de Camadas em Java EE

From Fragmental Bliki

Artigo sobre Arquitetura de Camadas em Java EE publicado pela revista Mundo Java em Janeiro de 2006 (edição 15). Este artigo foi baseado na palestra Maratona4Java2005: Arquitetura de Camadas em Java™ Enterprise Edition.

Conteúdo

Trecho de Introdução

A eterna luta pela qualidade no software vem há anos produzindo padrões e técnicas para a construção de sistemas com menos defeitos e de manutenção mais fácil e simples. Ainda na Época de Ouro do Projeto Estruturado de sistemas foram definidas duas métricas básicas para um módulo de software: Coesão e Acoplamento. Coesão é a medida em que os componentes de um módulo estão relacionados, se eles têm responsabilidades em comum ou se foram apenas agrupados por acaso. Acoplamento diz respeito à independência entre componentes, a medida do impacto que a alteração da implementação de um componente tem sobre outros. Componentes neste caso podem ser entendidos como classes em um pacote, linhas de código em um método, responsabilidades de uma classe ou qualquer coisa neste sentido. A aplicação destas métricas não está restrita a objetos, trechos de código ou atributos, elas também são aplicadas à arquitetura de uma aplicação. O uso de Camadas (Layers) é um Padrão Arquitetural que ajuda na tarefa de separar responsabilidades, promovendo baixo acoplamento e alta coesão em um sistema. O objetivo deste artigo é descrever este Padrão e apresentar técnicas que ajudam na implementação das Camadas mais comuns: Apresentação, Aplicação, Negócios e Persistência.

Comentários Comentados

Quando Evitar Camadas?

Bom dia Phillip.

Primeiramente parabéns pelo artigo publicado na Revista Mundo Java número 15. Se me permite, gostaria de fazer alguns comentários  
sobre o texto.
  
De maneira geral, evite camadas para:

 ·         [...]
 
 ·         Protótipos  (Protótipos por natureza não possuem código de implementação, pois são e devem ser utilizados somente na  
fase de  análise, freqüentemente, como, mecanismo de validação dos requisitos elicitados. Logo, em teoria, protótipos em hipótese  
alguma terão  camadas, código. Qual foi a mensagem do autor ao mencionar esse item?)
  
·         Partes de a aplicação que envolva relatórios pesados. Não ficou claro o porquê da sua colocação. Então a parte da  
apresentação toma conhecimento das outras camadas? Uma coisa é estratégica de implementação, normalmente, devido a limitações da  
plataforma, a outra, é definição de arquitetura de software.

 Uma colocação que visualizo como um mito:

 
"Muitos usuários novatos em Java  acabam se assustando quando ouvem que para fazer aquilo que para eles é supersimples em Visual  
Basic  ou Delphi leva horas e milhares de linhas de código escritas a mão em Java. (sic) [...] Para aplicações simples, pode ser 
útil  investigar outras plataformas especializadas como Ruby on Rails, Ruby ou Python com alguma biblioteca Groovy, Beanshell, 
JRuby ou  Jython[...] "

Nesses trechos do artigo há a alusão de que problemas distintos podem ser resolvidos com o acréscimo ou uso de linguagens ou  
frameworks de desenvolvimento. O que não é verdade. Primeiramente faz-se necessário deixar claro o que caracteriza uma aplicação   
simples. Segundo, a complicação então elicitada pelo desenvolvedor Delphi ou VB no desenvolvimento de uma aplicação Java em 
comparação  ao paradigma RAD das "linguagens" mencionadas, não são resolvidos simplesmente com o uso de outras linguagens ou 
framework. E.g. Ruby,  Ruby on Rails, pois, tem de ser levado em conta questões como tempo de aprendizado e o mais importante, a 
correta constatação dos  ganhos ao escolher pela utilização de uma tecnologia. 

Uma coisa é você ter vivido a situação, problema. A outra totalmente diferente é você acreditar por ter lido, ouvido. Gosto dessa  
citação: "Uma coisa é você dizer que conhece um caminho por ter trilhado nele, a outra, falar que  conhece o caminho, mas, nunca 
por  ele ter trilhado."[Autor desconhecido].

Por fim, achei um pouco confuso e ate mesmo antagônico as frases:

"Se você está produzindo um protótipo ou qualquer outro tipo de versão que seja temporária, sem manutenção, não vale a pena gastar  
muito tempo numa arquitetura decente. [...] (muitos softwares em produção vieram diretamente de protótipos em tirar nem pôr)." 
Software  demanda evolução contínua, atrelado às técnicas de reestruturação (refactoring), senão é software "morto". Novamente a 
referência à  estratégia de prototipação.

 Uma pequena observação que gostaria de fazer em relação ao glossário, diz respeito a atribuição do padrão de projeto "Observer" a  
Sun, e não ao grupo dos quatro amigos, GoF.

[]'s

Alessandro

Oi,


On 1/19/06, Alessandro Leite <alessandro.leite@gmail.com> wrote:
> Primeiramente parabéns pelo artigo publicado na Revista Mundo Java número
> 15. Se me permite, gostaria de fazer alguns comentários sobre o texto.

Obrigado :)

> De maneira geral, evite camadas para:

Note o "de maneira geral", a intenção foi explicitar que não são regras rígidas (como nada no artigo aliás) mas apenas recomendações em linhas gerais.

> ·         Protótipos  (Protótipos por natureza não possuem código de
> implementação, pois são e devem ser utilizados somente na fase de análise,
> freqüentemente, como, mecanismo de validação dos requisitos elicitados.
> Logo, em teoria, protótipos em hipótese alguma terão camadas, código. Qual
> foi a mensagem do autor ao mencionar esse item?)

Protótipos não são utilizados apenas num projeto de software. Muitas vezes são utilizados protótipos para exibir ao seus futuros clientes o que se pretende vender, por exemplo. Se você inventar uma tecnologia de, digamos, apresentação inovadora e precisa montar uma aplicação para pessoas que podem investir dinheiro na sua empresa, você não vai precisar de um produto completo e seguindo todas as melhores práticas. As vezes não é nem precisar, é simplesmente não ter tempo ou outro recurso. Neste caso você vai precisar de um protótipo que mostre todos os recursos da sua nova tecnologia em uma aplicação que funcione.

> ·         Partes de a aplicação que envolva relatórios pesados. Não ficou
> claro o porquê da sua colocação. Então a parte da apresentação toma
> conhecimento das outras camadas? Uma coisa é estratégica de implementação,
> normalmente, devido a limitações da plataforma, a outra, é definição de
> arquitetura de software.

Existe um problema clássico de manipulação pesada de dados e Orientação a Objetos. Objetos não ão amigáveis a manipulação direta de grandes quantidades de dados, pelo menos por enquanto.

Para as partes da sua aplicação que fazem transformações deste tipo, que geralmente não modificam dados, você pode ter uma perda considerável de performance ao utilizar um modelo de objetos, seja com bancos relacionais ou OO. Caso esta perda não seja relevante, ótimo, temos um cenário ideal, porém em muitos casos isso não é verdade.

Nos casos onde a performance de manipular dados com objetos é muito ruim, a melhor maneira que conheço é utilizar ferramentas próprias para isso. Geralmente implica em replicar regra de negócio, porém não há muitas alternativas.

Acho que o que faltou foi dizer o que é um "relatório pesado" no contexto e realmente admito que é uma omissão grave conhecendo o público-alvo. O problema é que depende do cenário. Em alguns casos trafegar objetos que representam relatórios entre Camadas é trivial mas em outros, talvez por restrição em tempo de resposta ou recursos o mesmo objeto-relatório é pesado demais.

A idéia da recomendação é evitar over-enginnering.

>  Uma colocação que visualizo como um mito:
>
>  ...
> Nesses trechos do artigo há a alusão de que problemas distintos podem ser
> resolvidos com o acréscimo ou uso de linguagens ou frameworks de
> desenvolvimento. O que não é verdade. Primeiramente faz-se necessário deixar
> claro o que caracteriza uma aplicação simples. Segundo, a complicação então
> elicitada pelo desenvolvedor Delphi ou VB no desenvolvimento de uma
> aplicação Java em comparação ao paradigma RAD das "linguagens" mencionadas,
> não são resolvidos simplesmente com o uso de outras linguagens ou framework.
> E.g. Ruby, Ruby on Rails, pois, tem de ser levado em conta questões como
> tempo de aprendizado e o mais importante, a correta constatação dos ganhos
> ao escolher pela utilização de uma tecnologia.

Acho que você está levando um "pode ser interessante" como uma recomendação absoluta. Eu não falei (creio) que utilizar A ou B iria resovler todos os seus problemas, apenas que deve ser considerado.

mesmo assim, dependendo do seu problema uma plataforma especializada pode resolvê-lo melhor que uma genérica, ou não. Depende do problema e sempre vai depender e isso deve ser levado em conta em qualquer recomendação.

Desenvolver uma aplicação web simples num cenário especializado para aplicações web simples feitas rapidamente, como Rails, provavelmente vai ter uma produtividade mais elevada após a curva de aprendizagem (note o "provavelmente" e o "curva de aprendizagem"). O problema é que nem toda aplicação pode ser construída em Rails ou valeria a pena o ser.

São canhões e moscas. O artigo fala sobre uma arquitetura que pode ser aplicado a qualquer sistema mas por vezes não vale a pena. O mesmo para Java, plataforma e linguagem.

O ponto do meu comentário é: "se você for fazer algo simples, simples mesmo, talvez seja melhor nem Java você usar. Se precisar de alguma biblioteca que só existe em Java ou quiser tirar proveito de sua excelente VM, veja uma destas linguagens mais simples que ainda assim tiram proveito da plataforma."

> Uma coisa é você ter vivido a situação, problema. A outra totalmente
> diferente é você acreditar por ter lido, ouvido. Gosto dessa citação: "Uma
> coisa é você dizer que conhece um caminho por ter trilhado nele, a outra,
> falar que  conhece o caminho, mas, nunca por ele ter trilhado."[Autor
> desconhecido].

Não entendi o que você quis dizer com isso. Se é uma contenstação sobre meu conhecimento prático em situações onde Java e/ou uma arqutietura bem planejada não eram o melhor a se fazer, o que posso dizer é que vivo isso diariamente desde que comecei a trabalhar.

> "Se você está produzindo um protótipo ou qualquer outro tipo de versão que
> seja temporária, sem manutenção, não vale a pena gastar muito tempo numa
> arquitetura decente. [...] (muitos softwares em produção vieram diretamente
> de protótipos em tirar nem pôr)." Software demanda evolução contínua,
> atrelado às técnicas de reestruturação (refactoring), senão é software
> "morto". Novamente a referência à estratégia de prototipação.

Realmente isso ficou confuso. A idéia a ser passada é de quue muitos softwares vão para produção diretamente do protótipo, por pior que isso possa parecer. Se você não cuidou da arquitetura do protótipo (ou pelo menos a deixou flexível o suficiente), pode ter problemas com este possível acontecimento.

>  Uma pequena observação que gostaria de fazer em relação ao glossário, diz
> respeito a atribuição do padrão de projeto "Observer" a Sun, e não ao grupo
> dos quatro amigos, GoF.

Perfeito, erro de Ctrl+C Ctrl+V meu :)

[]s

-- Phillip Calçado

Eu tenho um Mochileiro?

Philip,

tomando um pouco do seu tempo (e conhecimento!):

-estamos desenvolvendo um aplicativo p/escritorios de contabilidade
(folha, fiscal, contabil.. etc).
-estamos desenvolvento pensando em web e GUI:
(Cliente) GUI -> RMI -> (Servidor) -> RMI -> SPRING -> HIBERNATE;
portanto existem 2 camadas e varias layers...
  
Mas lendo sua apresentaçao do Maratona4Java2005, me assustei com o
termo: MOCHILEIRO DAS GALAXIAS.
 
Bah!, nossos 'objetos' realmente fazem isto, vao do servidor ao
cliente, passando pelas camadas e layers.
 
Como faço para contornar isto? Qual a melhor pratica?
 
Desde ja agradeço.

--
Rodrigo


Oi,

Pelo seu exemplo me parece que não é um caso típico de "mochileiro". Seu objeto atravessaria Camadas Físicas e como não existe uma relação 1 para 1 entre Físicas e Lógicas, não necessariamente isto cai no Antipattern.

Seu objeto seria um mochileiro se ele, por exemplo, é criado na Camada de Apresentação e segue para a Camada de Persistência, passando por Camadas de Aplicação e Negócios sem se alterar, ou o contrári: é instanciado na Persistência e chega exatamente da mesma forma na Apresentação.

Claro que como todo Pattern ou Antipattern existem ocasiões onde se aplica, mas se o exemplo mencionado acima acotnecer em excesso pode significar que você tem lógica de negócio apenas nas duas "pontas" (Apresentação e Persistência) e as Camadas intermediárias não fazem nada a maior parte do tempo.

...

[]s

-- Phillip Calçado


Implementei Camadas Corretamente ?

Veja a thread no GUJ: http://www.guj.com.br/posts/list/41032.java

Ola. Vejam o exemplo q eu fiz, só pra saber se estou indo certo ou nao.

to seguindo as camadas: apresentacao->aplicacao->negocio->persistencia. to com duvida  
na frase: "programe para interface e não para implementação". não sei a maneira 
correta de chamar uma camada a partir de outra...

Minha grande duvida é essa: qual é a maneira correta de fazer as camadas se  
comunicarem??  
...

Referências

Revista Mundo Java

Maratona4Java2005: Arquitetura de Camadas em Java™ Enterprise Edition - Palestra que Originou a Matéria

Ferramentas pessoais