Você está na página 1de 30

INTRODUO

21

PA R T E

I
Linguagem de padres EJB

Padres de arquitetura da camada EJB

23

CAPTULO

1
Padres de arquitetura da camada EJB

Ao projetar sistemas EJB (Enterprise JavaBean) pela primeira vez, a escolha de uma arquitetura correta, ou o particionamento de lgica, que satisfaa a preocupaes do projeto, como desempenho, manuteno e portabilidade, uma das tarefas mais difceis encontradas pelos desenvolvedores. Este captulo cobre alguns padres de arquitetura bsicos atualmente em uso na indstria, especificamente: Session Faade. O mais usado de todos os padres de projeto EJB, ele mostra como particionar adequadamente a lgica de negcio em seu sistema para ajudar a minimizar as dependncias entre cliente e servidor, ao mesmo tempo em que fora os casos de uso a serem executados em uma chamada de rede e em uma transao. Message Faade. Este padro discute quando e como particionar a lgica de casos de uso que sejam assncronos por natureza. EJB Command. Sendo a anttese do padro Session Faade, este padro advoga a colocao da lgica de negcio em Command Beans Java pequenos e simples. Os maiores benefcios deste padro so o completo desacoplamento do cliente em relao ao prprio EJB e a execuo de casos de uso em uma chamada de rede e em uma transao. Data Transfer Object Factory. Desmistifica a velha prtica de colocar a lgica de criao/ uso de DTOs no prprio Entity Bean e prescreve a centralizao da lgica de criao e uso do objeto de transferncia de dados para uma nica camada (implementada como Session Beans ou fbricas Java normais). Generic Attribute Access. Este padro discute quando e como fornecer uma interface de domnio genrico para os atributos de um Entity Bean para fins de manuteno e desempenho. Business Interface. Este padro mostra como implementar um esquema de implementao de interface que possa fornecer checagem em tempo de compilao das assinaturas dos mtodos nas interfaces Remota/Local e na classe EJB Bean.

24

CAPTULO 1

SESSION FAADE
Um cliente EJB precisa executar a lgica de negcio para completar um caso de uso. Como um cliente EJB pode executar a lgica de negcio de um caso de uso em uma transao e em uma chamada de rede? *** Para executar a lgica de negcio de um caso de uso tpico, em geral, diversos objetos no lado servidor (como Session Beans ou Entity Beans) precisam ser acessados e possivelmente modificados. O problema que diversas chamadas de granularidade fina a Session ou Entity Beans adicionam o overhead causado por diversas chamadas de rede (e possivelmente diversas transaes), alm de contriburem para dificultar a manuteno do cdigo, j que o acesso a dados e lgica de negcio ficam espalhados pelos clientes. Considere um cenrio de um banco online onde um servlet recebe um pedido de transferncia de fundos de uma conta para outra em nome de um cliente Web. Neste cenrio (conforme mostrado na Figura 1.1), o servlet deve checar para se assegurar de que o usurio tenha autorizao, retirar os fundos de um Entity Bean de conta bancria e deposit-los em outro. Ao executar mtodos nas interfaces Home e remotas dos Entity Beans, esta abordagem no suportar aumentos srios de carga, pois o cenrio inteiro requer pelo menos seis chamadas de rede: trs para encontrar os Entity Beans apropriados e mais trs para realmente transferir os fundos. Alm disso, tendo em vista que Entity Beans so entes transacionais, cada chamada de mtodo em uma entidade exigir uma transao separada no lado do servidor, demandando sincronizao da entidade remota com seus dados armazenados e manuteno por parte do servidor de aplicao. O pior que esta abordagem no garantir a segurana do dinheiro do cliente. Se algo der errado com o depsito, esse dinheiro j ter sido retirado e estar perdido. A checagem da autorizao do usurio, a retirada e o depsito so todos executados completamente parte e, se o depsito falhar, a retirada no ser desfeita, resultando em um estado inconsistente. Neste caso, o problema que, ao se chamar um mtodo de um Entity Bean diretamente, cada chamada de mtodo uma unidade de trabalho separada e uma transao separada.

FIGURA 1.1 Cliente transferindo fundos entre Entity Beans.

Padres de arquitetura da camada EJB

25

Uma soluo colocar lgica adicional dentro de nossos Entity Beans para desempenhar muitas operaes em uma nica chamada do cliente. Esta soluo causa problemas de manuteno, porque nossa camada de Entity Beans ser provavelmente usada de muitas formas diferentes com o decorrer do tempo. Se adicionarmos lgica de aplicao a nossos Entity Beans cada vez que precisarmos de uma melhoria de desempenho, eles iro rapidamente inchar e se tornar difceis de entender, realizar manuteno e reusar. Estamos juntando nossa lgica da aplicao (verbos) com nossa lgica de persistncia (substantivos), o que um desenho de aplicao de qualidade inferior. Outra abordagem nosso cliente demarcar uma transao grande e agregada por meio da API Java Transaction (JTA). Isto faria cada chamada de mtodo de um Entity Bean operar sob a mesma transao, executando tudo ou nada. Se o depsito falhar, ento a retirada ser desfeita e o dinheiro do usurio estar seguro. Entretanto, esta soluo aprimorada ainda tem muitas desvantagens: Alto overhead de rede. Ainda temos seis chamadas de rede com que trabalhar, as quais diminuem o desempenho (a no ser que usemos interfaces locais). Baixo grau de concorrncia. Se o cliente estiver muito distante do servidor (como no caso de uma applet ou aplicao interagindo com um sistema EJB remoto, talvez at mesmo pela Internet ou por meio de um firewall), a transao ir durar bastante tempo. Isto acarreta excesso de bloqueios, aumentando a chance de colises ou deadlock, e reduz o grau de concorrncia de outros clientes acessando as mesmas instncias de Entity Bean. Alto grau de acoplamento. Nosso cliente escreve diretamente para uma API de Entity Bean, o que o acopla fortemente ao Entity Bean. Caso a camada do Entity Bean precise de alterao no futuro, deveremos alterar tambm o cliente. Baixo grau de reuso. A lgica de negcio que executou o caso de uso transferncia de fundos estava embutida diretamente no cliente. Por isso, ela fica presa quele cliente. Outros tipos de clientes (aplicaes Java, applets, servlets e assim por diante) no podem reusar esta lgica de negcio. Esta mistura de lgica de apresentao com lgica de negcio um projeto de aplicao de qualidade inferior para qualquer distribuio sria. Baixo grau de manuteno. O uso da API Java Transaction deixa a lgica do middleware para a realizao de transaes entrelaada com a lgica da aplicao. muito mais legvel separar as duas por meio de transaes declarativas, de forma que possamos refinar e ajustar nosso middleware sem afetar nossas regras de negcio. Baixa separao dos papis de desenvolvimento. Uma prtica comum em projetos grandes separar os programadores das tarefas de desenvolvimento da lgica de apresentao (como desenvolvedores de servlets/jsp) dos programadores da lgica de negcio/middleware (desenvolvedores EJB). Se a lgica de negcio for codificada na camada cliente/apresentao, no ser possvel uma separao clara de papis. A lgica de negcio e a de apresentao iro atrapalhar uma outra caso sejam programadas na camada de apresentao. O ponto importante de nossa discusso que precisamos de uma abstrao do lado servidor que sirva de intermediria e armazene as chamadas para Entity Beans. Session Beans so projetados para isso. Portanto: Envolva a camada de Entity Beans em uma camada de Session Beans chamada Session Faade. Os clientes devem ter acesso apenas aos Session Beans, no aos Entity Beans. O padro Session Faade aplica os benefcios do padro Faade tradicional EJB escondendo completamente da camada cliente o modelo de objetos no servidor, de modo que uma camada de Session Beans seja o nico ponto de acesso ao cliente. A Figura 1.2 ilustra como a arquitetura pode ser melhorada adotando esta abordagem. O padro Session Faade tambm inclui os benefcios de garantir a execuo de um caso de uso em uma chamada de rede e fornecer uma camada limpa para encapsular as lgicas de negcio e de workflow usadas para satisfazer aos casos de uso. O Session

26

CAPTULO 1

FIGURA 1.2 Os benefcios arquitetnicos de Session Faade.

Faade normalmente implementado como uma camada de Session Beans sem estado (embora o padro tambm possa ser implementado com Session Beans com estado). Para ilustrar o modo como este paradigma funciona e seus benefcios, usaremos o exemplo anterior. Nossa lgica de negcio para o caso de uso de transferncia de fundos ser agora colocada em um Session Bean que contm um mtodo chamado transferFunds(userpk, accountpk, accountpk, amount). O Session Bean BankTeller executa, deste modo, grandes operaes sobre Users e Bank Accounts, conforme mostrado na Figura 1.3. J que o Session Bean BankTeller est colocado junto com os Entity Beans User e Account, deve ser codificado explicitamente para se comunicar com os Entity Beans por meio de suas interfaces locais, reduzindo assim o overhead de rede necessrio para executar este caso de uso para apenas uma chamada (a chamada do cliente para o BankTeller). Alm disso, todas as atualizaes na camada dos Entity Beans devem ser executadas dentro da transao iniciada pelo BankTeller quase sempre definida no seu descritor de localizao com uma configurao de TX_REQUIRED.

FIGURA 1.3 Os benefcios de desempenho do Session Faade.

Padres de arquitetura da camada EJB

27

Isto efetivamente envolve todo o caso de uso dentro de uma transao, garantindo que todas as atualizaes sobre os Entity Beans sejam executadas dentro da transao iniciada na execuo do mtodo transferFunds do BankTeller. O padro Session Faade o padro EJB mais importante em uso (e por isso o primeiro deste livro). Ele no apenas fornece benefcios em termos de desempenho, como tambm sugere uma arquitetura padro para sistemas EJB, particionando suas aplicaes J2EE de forma que a fronteira entre o cliente e o servidor seja separada por uma camada de Session Beans, cujos mtodos mapeiam (e contm a lgica de negcio de) todos os casos de uso na aplicao. Levando o exemplo do BankTeller mais adiante, obviamente h mais casos de uso envolvendo a aplicao bancria do que simplesmente a transferncia de fundos. Usando o padro Session Faade, seriam criados Session Beans para agrupar os casos de uso com funes semelhantes em um nico Bean. Deste modo, poderamos adicionar outras operaes bancrias subordinadas ao BankTeller (como withdrawFunds, depositFunds, getBalance()). Em outro local na aplicao bancria, casos de uso com propsitos diferentes tambm seriam agrupados em um Session Bean. Por exemplo, cada banco tem um Departamento de Emprstimos. Os casos de uso necessrios para modelar as operaes deste departamento no so relacionados aos casos de uso de um BankTeller. Desta maneira, eles seriam agrupados em um Session Bean LoanServices. De maneira similar, uma aplicao bancria tambm precisaria de um Session Bean para encapsular casos de uso relacionados a investimentos. Usando o padro Session Faade, a aparncia da arquitetura desta aplicao bancria se pareceria com a Figura 1.4. O padro Session Faade funciona to bem que muitas vezes fcil abusar dele. comum encontrar projetos nos quais o Session Faade est sendo usado de forma errada: Criao de um nico Session Bean. Muitas vezes, os desenvolvedores colocam todos os casos de uso de um sistema em um nico Session Bean, o que resulta em um Session Bean inchado e em menor produtividade no desenvolvimento, porque todos os desenvolvedores pre-

FIGURA 1.4 Aparncia da arquitetura agrupando-se casos de uso em Session Beans.

28

CAPTULO 1

cisam acessar esta nica classe. Os Session Beans devem ser divididos para abrigar grupos de casos de uso relacionados. Colocao da lgica do domnio em Session Beans. Um modelo de domnio orientado a objetos bem projetado deve conter toda a lgica de negcio/casos de uso na sua aplicao (Fowler, 2001). A maioria dos mtodos do Session Faade deve simplesmente delegar para o Entity Bean apropriado, a no ser que o caso de uso envolva lgica de workflow que precise operar sobre diferentes Beans que possam no estar diretamente relacionados. Duplicao da lgica de negcio pela fachada. medida que o projeto cresce, muitas vezes, os mtodos de um Session Bean contm cdigo duplicado, como a lgica da execuo de checkCreditHistory, que poderia ser parte do workflow para outros casos de uso. A soluo acrescentar uma camada de servios (implementada como Session Beans ou em classes Java) que encapsule esta lgica de negcio reusvel e independente de casos de uso. Esta camada de servios escondida do cliente. medida que os projetos aumentam de tamanho, til realizar sesses de refatorao regularmente, nas quais a lgica duplicada encontrada e extrada. A seguir, esto os benefcios do padro Session Faade: Baixo overhead de rede. Na medida em que a camada de Session Beans acrescenta uma camada extra por meio da qual as chamadas devem passar, o cliente pode agora transferir fundos em apenas uma chamada de rede, em vez de seis. No servidor, o Session Bean se comunica com Entity Beans por interfaces locais, no incorrendo, portanto, em qualquer overhead na rede. Mesmo com os Entity Beans sendo usados apenas por interfaces remotas, a maioria dos servidores de aplicao otimizaria a comunicao entre os EJBs no mesmo servidor. Separao clara e rgida entre as lgicas de negcio e da camada de apresentao. Usando um Session Faade, a lgica necessria para executar a lgica de negcio fica completamente envolvida por trs de mtodos nos Session Beans. Os clientes EJB s precisam se preocupar com questes da camada de apresentao e nunca deveriam ter de executar mais de um mtodo em um EJB para obter uma unidade de trabalho executada. Isto separa rigidamente a lgica de negcio da lgica da camada de apresentao. Integridade transacional. Nosso Session Bean encapsula toda a lgica para executar a transferncia bancria em uma transao. O Session Bean age portanto como uma fachada transacional, a qual localiza as transaes no lado do servidor e as mantm curtas. As transaes tambm so demarcadas em nvel de mtodo de Session Bean, configurveis por meio de descritores de localizao. Baixo acoplamento. O Session Bean armazena pedidos entre o cliente e os Entity Beans. Se a camada dos Entity Beans precisar mudar no futuro, poderemos evitar mudanas no cliente devido camada de indireo de Session Beans. Boa reusabilidade. A lgica de nosso caixa de banco fica encapsulada em um Session Bean modular e pode ser acessada por qualquer tipo de cliente (JSPs, servlets, aplicaes ou applets). O encapsulamento da lgica da aplicao em Session Beans significa que nossos Entity Beans podem conter dados e lgica de acesso apenas a dados, tornando-os reusveis pelos Session Beans na mesma ou at em diferentes aplicaes. Boa capacidade de manuteno. Deve-se definir a transao de forma declarativa no descritor de localizao do Session Bean BankTeller, em vez de faz-lo por meio de programao via JTA. Isto nos d uma clara separao entre o middleware e a lgica da aplicao, o que aumenta a capacidade de manuteno e diminui a probabilidade de erros. Separao verbo-substantivo clara. A camada de Session Beans modela os casos de uso especficos da aplicao, os verbos da nossa aplicao, enquanto a camada de Entity Beans modela os objetos do negcio, ou os substantivos, da nossa aplicao. Esta arquitetura torna muito fcil mapear casos de uso de um documento de requisitos para uma arquitetura real EJB.

Padres de arquitetura da camada EJB

29

O padro Session Faade uma base no desenvolvimento EJB. Refora um projeto altamente eficiente e reusvel, alm de separar claramente as lgicas da apresentao (o cliente), de negcio (a fachada de sesso) e de dados (Entity Beans e assim por diante). O Session Faade descreve uma arquitetura til para implementar qualquer tipo de caso de uso; entretanto, se o caso de uso for assncrono por natureza, o padro Message Faade fornecer uma abordagem mais escalvel.

Padres relacionados
Message Faade Data Transfer Object Session Faade (Alur et al., 2001) Session Faade (MartinFowler.com)

MESSAGE FAADE
Um cliente Enterprise Java Bean quer chamar os mtodos de diversos EJBs dentro do contexto de um caso de uso e no requer uma resposta imediata do servidor. Como um cliente EJB pode chamar os mtodos de diversos Session Beans ou Entity Beans dentro de uma transao sem precisar bloquear e esperar respostas de cada Bean? * * * Especialmente em sistemas grandes, a escalabilidade dita que a lgica de negcio de um caso de uso seja executada separadamente da lgica do cliente, sem exigir que este espere at que a execuo esteja completa. Este tipo de comportamento, chamado assncrono, permite aos clientes interagirem com a interface de usurio (UI User Interface) com tempos de resposta mximos, porque eles no precisam sentar e esperar enquanto o caso de uso que foi iniciado executado. Esta abordagem permite a um sistema grande crescer, porque os casos de uso podem ser enfileirados e operados em lote, de modo transparente para o usurio, que instantaneamente passa para a prxima parte de uma interface de usurio. As partes do sistema que realmente executam os casos de uso tambm podem ser ampliadas e sofrer atualizaes se comear a haver acmulo de casos de uso na fila, tudo sem alterar a qualidade ou disponibilidade do servio para os clientes. Considere um sistema de registro de passagens areas simples baseado na Web no qual um servlet recebe uma solicitao para reservar um lugar para um usurio em um vo especfico. Neste cenrio, o servlet deve registrar um usurio em um avio, determinar se os assentos esto disponveis no vo e, em caso afirmativo, reservar um para o usurio, conforme mostrado na Figura 1.5 (p. 30). Neste exemplo, temos um cliente executando diversas chamadas sncronas para o servidor para executar um caso de uso. Cada passo do processo requer uma chamada de rede separada e o bloqueio por parte do cliente. Em um sistema pesado como uma aplicao de reserva de passagens areas, este gargalo obviamente inaceitvel. Alm disso, executar a lgica desta forma reduz o grau de capacidade de manuteno e o reuso do sistema e no fornece consistncia de transao ou isolamento para o caso de uso. A soluo mais comum usar o padro Session Faade. Com ele, uma aplicao cria uma camada de Session Beans que contm a lgica de negcio para satisfazer aos casos de uso de negcio. Cada Session Bean executa uma grande quantidade de operaes sobre Entity Beans ou outros recursos no lado servidor em nome dos clientes em uma chamada grande, conforme mostrado na Figura 1.3 no padro Session Faade. Infelizmente, mesmo se o caso de uso inteiro estiver envolvido em um mtodo do Session Faade, a abordagem ainda apresenta diversas desvantagens: Tempo de resposta inaceitvel. Um usurio interagindo com um website no esperar por muito mais do que alguns segundos. A execuo deste caso de uso requer muito processamento em segundo plano, que poderia abranger diversas bases de dados em diversos sistemas de

30

CAPTULO 1

FIGURA 1.5 Caso de uso Reserve Seat.

reservas. Devido ao fato de a chamada EJB ser sncrona, o cliente teria que bloquear at que o processo inteiro tivesse sido completado. Falta de tolerncia a falhas. Este caso de uso poderia envolver EJBs espalhados por at trs instncias de servidores EJB e trs bancos de dados separados (uma para usurios, uma para empresas areas e uma para vos). Se qualquer um desses bancos de dados estivesse fora do ar, o processo inteiro falharia e o pedido de reserva do usurio seria perdido. Mesmo se a camada do servlet estivesse se comunicando com apenas um servidor EJB, o processo falharia se o servidor estivesse fora do ar. Usar o Session Faade resolve os problemas de acoplamento, desempenho, manuteno, reuso e consistncias, mas no resolve completamente os de tempo de resposta e confiabilidade. O cliente ainda tem de realizar bloqueio enquanto um caso de uso complexo e que consome muito tempo executado. O caso de uso tambm falhar se o servidor EJB ou qualquer um dos sistemas dos quais ele dependa no estiver rodando no momento em que o caso de uso for executado. O ponto importante da nossa discusso que precisamos de uma abstrao do lado servidor tolerante a falhas que sirva como intermediria, executando os casos de uso em uma chamada e uma transao (resguardando os clientes das complexidades do modelo de objetos do lado servidor) e que no requeira que o cliente bloqueie e espere at o caso de uso ser completado. Beans orientados a mensagens so projetados apenas para isso. Portanto: Use Beans orientados a mensagens para criar uma fachada tolerante a falhas e assncrona. Os clientes devem ter acesso apenas a Beans orientados a mensagens, no a Entity Beans. Usar Beans orientados a mensagens (MDB Message-driven Beans) como fachada melhora o padro Session Faade ao adicionar a capacidade de execuo de casos de uso de uma maneira assncrona e tolerante a falhas. Quando usamos uma fachada de mensagem, a lgica de negcio em cada um dos casos de uso de uma aplicao mapeia para seu prprio MDB. Considere o exemplo anterior. Nossa lgica de negcio para reserva de lugares em um vo ser agora colocada no mtodo onMessage( ) em um Bean orientado a mensagens ReserveSeat. O objetivo

Padres de arquitetura da camada EJB

31

deste MDB encapsular toda a lgica de negcio/workflow relacionada reserva de lugares em um vo e executar assincronamente, conforme mostrado na Figura 1.6. Aqui temos um servlet cliente criando uma mensagem Java Message Service (JMS) e passando os parmetros necessrios. O servlet constri uma mensagem contendo todos os parmetros necessrios (a chave primria do usurio, o nmero do vo, a chave primria do avio) e a envia para um destino JMS criado para o caso de uso Reserve Seat. Ao receber a mensagem no destino apropriado, o cliente ficar livre para prosseguir (mostrar a prxima pgina Web). O continer do Bean orientado a mensagens tentar passar a mensagem para o prximo Bean orientado mensagem ReserveSeat disponvel. Se todos os MDBs ReserveSeat no grupo estiverem sendo usados no momento da recepo da mensagem, o servidor JMS dever esperar at que o prximo esteja disponvel. Se este caso de uso tivesse sido executado por meio de uma fachada de sesso, um grupo de Session Beans completamente usado teria sido a nica falha e o cliente teria que tentar de novo manualmente. Uma vez que um MDB esteja disponvel, o continer executar o mtodo onMessage( ). Neste ponto, o Bean orientado a mensagens ReserveSeat ir registrar o usurio na empresa area, checar se os assentos esto disponveis e reservar um lugar linearmente atravs do processo de execuo do caso de uso. Enquanto este processo, que consome tempo, estiver ocorrendo, o usurio final ficar livre para navegar pelo site e trabalhar no seu negcio. Uma vantagem importante que o padro Message Faade tem sobre o Session Faade que se pode garantir casos de usos executados assincronamente. Isto significa que, se a transao falhar em algum ponto (talvez o sistema de reservas saia do ar ou qualquer outra falha de sistema ocorra), a transao ser desfeita e a mensagem JMS ser colocada de volta na fila. Uma nova tentativa de execuo da transao ser feita mais tarde, sem o conhecimento do cliente. Este comportamento por-trs-da-cena tambm apresenta um problema. Como o cliente ser notificado se o caso de uso falhar ou se for bem-sucedido? Por exemplo, se um lugar no puder ser reservado pelo fato de o avio estar lotado, o cliente precisaria ser notificado. Em um modelo sncrono (usando uma fachada de sesso), o cliente saberia imediatamente. Em um modelo assncrono, o cliente no estaria mais esperando para ver se o caso de uso foi bem-sucedido e precisaria ser alertado de alguma forma especfica para a aplicao. A soluo mais comum via correio eletrnico. Se o caso de uso for bem-sucedido ou falhar, o sistema notificar o usurio por e-mail. Algumas companhias podem implementar o sistema de modo que algum fizesse uma ligao telefnica, e assim por diante. Se os requisitos da aplicao permitirem, algumas aplicaes podero usar um modelo compartilhado. Isto significa que o usurio final receber um local aonde poder ir para checar o status de seus pedidos, de maneira similar ao nmero de rastreamento usado por servios de entrega modernos.

FIGURA 1.6 Caso de uso Reserve Seat com um Message Faade.

32

CAPTULO 1

O ponto a considerar aqui que, ao usar o padro Message Faade, os desenvolvedores devem planejar novas maneiras de se comunicar com o cliente sobre os resultados de um caso de uso. Uma desvantagem de usar o padro Message Faade que agora a lgica de negcio est distribuda atravs tanto dos Beans orientados a mensagem (pela fachada de mensagem) quanto dos Sessions Beans (pela fachada de sesso). Isto pode no ser uma preocupao importante para a maioria, mas seria bom manter a lgica de negcio em um nico local da aplicao. Uma maneira mais inteligente de resolver este problema implementar todos os casos de uso na prpria fachada de sesso e usar a fachada de mensagens para delegar fachada de sesso. Desta forma, todos os benefcios de usar uma construo assncrona e tolerante a falhas como um Bean orientado a mensagens so mantidos, ao mesmo tempo em que a lgica permanece na camada dos Session Beans. As vantagens do padro Message Faade incluem todas mostradas no padro Session Faade, como: Tempo de resposta instantneo/comunicao assncrona. Quando um cliente envia uma mensagem JMS, est livre para continuar processando sem esperar at que o servidor complete o caso de uso e responda. Um caso de uso comprido e complexo pode, assim, ser iniciado enquanto o controle de fluxo retorna instantaneamente ao usurio. Eliminao de pontos individuais de falha. O uso de mensagens garantir que sua aplicao continue a funcionar mesmo quando o servidor EJB ou outro subsistema do qual ele dependa sair do ar. Por exemplo, se o banco de dados no estiver funcionando, a transao do MDB no ser completada e a mensagem de reserva de lugar permanecer na fila, sendo feita nova tentativa mais tarde. Se o continer EJB estiver fora do ar, a mensagem ser armazenada novamente. Tais capacidades de superar falhas no seriam possveis se usssemos um modelo sncrono. claro que, se o seu servidor JMS no estiver clusterizado e sair do ar, isto ainda representar um ponto falho individual, mas pelo menos o nmero de possveis causadores de interrupo foi reduzido. Entretanto, como subproduto do uso de Beans orientados a mensagens, o padro Message Faade tambm apresenta alguns problemas: Beans orientados a mensagens tm parmetros de entrada fracamente tipados. O papel de um Bean orientado a mensagens consumir mensagens JMS, as quais parecem todas idnticas em tempo de compilao. Isto contrasta com os Session e Entity Beans, os quais alavancam a forte tipagem incorporada por Java aos mtodos e parmetros das interfaces remotas e locais para apanhar erros comuns em tempo de compilao. O desenvolvedor deve tomar cuidado extra para carregar uma mensagem JMS com o contedo apropriado requeridos pelo seu MDB destinatrio. Uma soluo para este problema encapsular todos os dados da mensagem JMS em um objeto de transferncia de dados customizado e serializ-lo na mensagem JMS. Beans orientados a mensagens no tm valores de retorno. J que as chamadas MDB so assncronas, o Message Faade no pode ser usado em casos de uso que demandem um valor de retorno aps a execuo. Portanto, usar o Message Faade , primeira vista, similar a usar o Session Faade, no qual todos os mtodos dos Session Beans simplesmente retornam void. Entretanto, possvel obter uma resposta de um Bean orientado a mensagens de volta para o criador da mensagem usando JMS como mecanismo de transporte. Veja no livro Mastering Enterprise Java Beans, Second Edition uma discusso sobre esse mecanismo. Beans orientados a mensagens no propagam excees de volta aos clientes. Diferentemente dos Session e Entity Beans, os Beans orientados a mensagens no podem gerar excees na aplicao ou RemoteException a partir de qualquer um de seus mtodos. Os MDBs devem, portanto, lidar com todas as excees apresentadas em algum formato especfico da aplicao (isto , enviando uma mensagem eletrnica para o usurio se algo tiver dado errado, colocando os erros em um log de administrao, e assim por diante).

Padres de arquitetura da camada EJB

33

O Message Faade um padro muito poderoso para a construo de aplicaes desacopladas e altamente escalveis. Um sistema EJB tpico provavelmente usaria uma combinao dos padres Session Faade e Message Faade. O Session Faade a melhor opo para operaes do tipo leitura, em que o cliente requer algum dado do servidor, ou quando o cliente precisa esperar visivelmente at que um caso de uso tenha sido completado. O Message Faade a melhor opo para operaes de atualizao, cujos resultados o cliente no precisa ver instantaneamente. Os benefcios relacionados a escalabilidade e tolerncia a falhas que o padro Message Faade tem em relao ao padro Session Faade so significativos. Em termos de desempenho, um sistema baseado em mensagens ir escalar melhor do que uma abordagem de Session Beans clusterizados, porque os Beans de mensagens puxam trabalho em vez de fazerem com que o trabalho seja empurrado para eles. Esta abordagem escala melhor quando clusterizamos, porque otimiza o uso dos recursos do sistema. Os desenvolvedores devem avaliar com cuidado cada caso de uso em seus projetos, perguntando a si mesmos se o caso de uso de natureza sncrona ou assncrona. Este ser um fator decisivo na preferncia de um padro a outro.

Padres relacionados
Session Faade

EJB COMMAND
Um cliente EJB precisa executar lgica de negcio para completar um caso de uso. Como um desenvolvedor pode implementar a lgica de negcio de um caso de uso de uma maneira leve, desacoplando o cliente do EJB e executando o caso de uso em uma transao e em uma chamada de rede? * * *

Uma deciso fundamental de arquitetura ao projetar um sistema EJB onde colocar a lgica de negcio. A lgica de negcio de um caso de uso a lgica que delega ao mtodo apropriado no seu modelo de domnio ou executa lgica que opera sobre diversos outros Entity Beans e/ou Session Beans (lgica de workflow). Colocar a lgica de negcio no cliente (servlets, applets e assim por diante) tem srias conseqncias negativas, afetando o desempenho e a manuteno, conforme explicado no padro Session Faade. Estes problemas podem ser corrigidos pelo uso do padro Session Faade, que requer que a lgica de negcio seja colocada em mtodos em Session Beans, sendo que cada mtodo em um Session Bean mapeia uma unidade particular de trabalho, ou caso de uso. Fazendo isso, h um escudo entre o cliente e o modelo de objetos no servidor, e os casos de uso so executados em uma transao e em uma ida e volta pela rede. O padro Session Faade uma base no desenvolvimento EJB, mas tambm apresenta as prprias fraquezas. Chamar a fachada de sesso diretamente a partir do cliente pode causar dependncias entre as equipes do cliente e do servidor em um projeto grande e complicar o cdigo do cliente devido ao forte acoplamento ao EJB, conforme discutido no padro Business Delegate. Estes problemas podem ser minorados pelo uso de encarregados de negcios, o que acrescenta uma camada de objetos que encapsulam todo o acesso na camada EJB. Business Delegates podem ajudar a manter o cdigo cliente simples, minimizando as dependncias entre cliente e servidor. Portanto, o padro Session Faade, combinado com o padro Business Delegate, fornece uma prtica melhor para escrever lgica de negcio em um formato que desacopla o cliente dos detalhes de implementao do servidor e permite a execuo de casos de uso em uma chamada de rede e em uma transao. Como sempre, h compensaes:

34

CAPTULO 1

Processo mais lento de desenvolvimento. Devido ao fato de a lgica do caso de uso (que pode mudar freqentemente) ser executada em um Session Bean, toda vez que um caso de uso precisar ser alterado (isto , para acrescentar um parmetro a um mtodo ou retornar um atributo adicional), o mtodo do Session Bean que implementa esse caso de uso poder precisar ser alterado. O processo de alterao de um Session Bean no trivial uma mudana requer muitas vezes a edio de trs arquivos diferentes (interface, classe Bean, descritor de localizao), bem como a redistribuio no servidor EJB e a possvel reinicializao do servidor. Alm disso, o encarregado de negcios que encapsula o Session Bean alterado no cliente normalmente precisar tambm ser alterado. A diviso de trabalho em um projeto grande mais difcil. Dependendo das estratgias usadas para dividir o trabalho entre os desenvolvedores em um projeto, a fachada de sesso muitas vezes um gargalo com o qual diferentes equipes ou desenvolvedores iro lutar, j que ele pode estar sujeito a freqentes alteraes medida que o projeto progride. Os recursos do servidor muitas vezes so controlados por apenas uma equipe em uma corporao grande. Em corporaes grandes com conjuntos de EJBs distribudos j estabelecidos e funcionando, pode ser difcil para as equipes trabalhando em outros projetos efetuar mudanas em classes preexistentes. Resumindo, desenvolver com uma fachada de sesso e encarregados de negcios pode resultar em diversos ciclos altera-distribui-testa, o que pode se tornar um gargalo em um projeto grande. O ponto crucial do problema que a lgica de negcio est sendo colocada em uma camada de sesso EJB, cujo desenvolvimento pode ser bem pesado. Portanto: Use o padro Command para envolver lgica de negcio em Command Beans leves que desacoplem o cliente do EJB, executem em uma chamada de rede e ajam como uma fachada para a camada EJB. Um Command Bean apenas uma classe Java comum com gets, sets e um mtodo execute, conforme descrito no padro Command original (Gamma et al., 1995). Aplicado ao EJB, o padro Command fornece uma soluo leve para a obteno dos mesmos benefcios dos padres Session Faade e Business Delegate: uma fachada que esconde o modelo de objetos na camada EJB, a execuo de um caso de uso em uma transao e em uma chamada de rede, e o desacoplamento completo entre o cliente e o EJB. O padro Command consegue isto fornecendo aos clientes classes com as quais eles interagem localmente, mas que na verdade so executadas dentro de um servidor EJB remoto, transparente ao cliente. Os Commands so usados para encapsular unidades individuais de trabalho em uma aplicao. Um caso de uso como placeOrder, transferFunds e outros teria sua lgica de negcio/workflow encapsulada em um Command especial feito apenas para aquele caso de uso, como mostrado na Figura 1.7. A interao do cliente com um Command muito simples. Uma vez que o cliente obtenha um Command (seja criando um ou obtendo de uma fbrica, dependendo da implementao), ele simplesmente define atributos no Command, at que este contenha todos os dados necessrios para executar um caso de uso. Neste ponto, o cliente pode chamar o mtodo execute do Command e ento simplesmente executar gets no mesmo at que tenha recuperado todos os dados resultantes da execuo do Command/caso de uso. Quando o cliente executa o Command, coisas interessantes acontecem por trs da cena. Em vez de ser executado localmente, ele na verdade transferido para um servidor EJB remoto e executado dentro do JVM do servidor EJB. Assim, todos os EJBs chamados pelo Command durante a execuo de seu caso de uso ocorrem dentro do prprio servidor EJB. Quando o Command completa sua execuo, retornado para o cliente, o qual pode ento chamar mtodos get para recuperar dados. Fazendo o Command executar dentro do servidor EJB, o caso de uso pode ser executado dentro de apenas uma transao. A mecnica de implementao deste comportamento ser explicada mais adiante, na discusso deste padro.

Padres de arquitetura da camada EJB

35

FIGURA 1.7 A viso do cliente do Transfer Funds Command.

Usando o exemplo do transferFunds, o cliente definiria as IDs da conta cujos fundos so retirados, a conta na qual depositar o dinheiro e a quantidade a transferir. Depois de chamar execute do Command transferFunds, o cliente pode obter o saldo final das contas, conforme mostrado na Figura 1.8. provvel que uma das mais abrangentes implementaes do padro Command seja o framework Command da IBM, o qual vai com o Websphere, parte dos padres IBM para comrcio eletrnico. H muitas maneiras diferentes de implementar o padro EJB Command, mas todas elas tm os mesmos trs elementos: Command Beans. Uma classe simples Java Bean com gets, sets e um mtodo execute que contm a lgica de negcio necessria para executar um caso de uso. Os Command Beans so a

FIGURA 1.8 Usando um Transfer Funds Command.

36

CAPTULO 1

nica parte do padro Command que precisa ser escrita pelos desenvolvedores da aplicao. Os outros componentes explicados abaixo podem ser reusados pelo projeto. Lgica de roteamento no lado do cliente. Normalmente, um framework de classes responsvel por tomar um Command e envi-lo para o servidor EJB remoto. Esta lgica de roteamento geralmente invisvel para o cliente e disparada pela chamada do mtodo execute de um Command. A lgica/framework de roteamento um conjunto genrico de classes que pode ser reusado pelos projetos. Servidor de Comandos Remoto. O Servidor de Comandos Remoto um servio que simplesmente aceita comandos e os executa. Aplicada ao EJB, a classe CommandServer um Session Bean sem estado que aceita um Command como parmetro e o executa localmente. O CommandServer tambm genrico, podendo ser completamente reusado pelos projetos. As interaes entre o cliente e esses trs componentes so ilustradas na Figura 1.9. Neste exemplo, o cliente chama um mtodo executeCommand no componente de lgica de roteamento. No framework Command da IBM, o cliente s precisa chamar execute no prprio Command, j que a chamada do mtodo na verdade ser recebida pela superclasse do Command, a qual parte do framework de lgica de roteamento. Por trs da cena, o CommandExecutor delega a chamada para um EJBCommandTarget (no mostrado na Figura 1.9, j que faz parte da lgica de roteamento), o qual codificado com conhecimento do EJB e sabe como enviar o Command para o Session Bean sem estado CommandServer. Ao receber o Command, o CommandServer simplesmente chama o mtodo execute no Command, o qual ento cuida da lgica de negcio. Os benefcios do padro Command so: Facilita o Desenvolvimento Rpido de Aplicaes (RAD) devido ao processo leve de desenvolvimento e distribuio. Escrever um caso de uso como um Command Bean torna consideravelmente mais fcil e rpido distribuir e testar do que escrev-lo como mtodo de um Session Bean. As alteraes freqentes podem ser feitas em uma classe Java simples, de forma oposta a um EJB completo.

FIGURA 1.9 Interaes do padro Command.

Padres de arquitetura da camada EJB

37

Separa a lgica de negcio da lgica de apresentao. Os comandos agem com uma fachada para o modelo de objetos no servidor, encapsulando lgica de negcio dentro de Commands e expondo apenas uma interface simples de Command para os clientes usarem. Esta separao permite que o cliente e o servidor sejam desenvolvidos separadamente. Fora a execuo dos casos de uso em um nico ciclo. Tendo em vista que o Command na verdade executado no servidor EJB, necessria apenas uma chamada de rede (e transao) para completar um caso de uso complicado. Desacopla o cliente do EJB. Os clientes so completamente desacoplados dos detalhes da implementao do servidor tudo o que eles vem o Command Bean, o qual parece uma classe local. Comandos podem ser executados localmente ou produzir dados fictcios. No incio de um projeto, podem ser criados comandos vazios ou falsos, permitindo que os desenvolvedores da camada de apresentao escrevam, compilem e testem seu cdigo independentemente da lgica de negcio e da equipe EJB. Sob vrios aspectos, o padro Command parece ser a soluo final, combinando os benefcios dos padres Session Faade e Business Delegate com uma infra-estrutura mais leve. Entretanto, os benefcios so, como sempre, contrabalanceados por desvantagens importantes: Controle de transao com granularidade muito grossa. J que os Commands so apenas Java Beans simples, no h maneira automtica de marcar um Command para rodar sob um determinado nvel de isolamento ou de ajuste de uma transao, como voc pode fazer com mtodos de Session Beans. Os comandos podem ser executados apenas sob o ajuste da transao do CommandServer que os executa. Para evitar isso, preciso distribuir diversos Session Beans do servidor de Commands com diferentes nomes jndi e ajustes de transao (configurados nos descritores de localizao). O componente da lgica de roteamento precisa ser configurado para enviar certos Commands para certos servidores de Commands. Isto significa que se pode desejar enviar todos os Commands s de leitura para Session Beans que rodam sem transaes, ao passo em que os Commands de atualizao poderiam ser executados em um servidor de Commands rodando com tx_requires e nvel de isolamento serializvel. Comandos no tm estado. O objeto Command no pode armazenar qualquer estado no Session Bean que o executa. Portanto, com o padro Command, no possvel o armazenamento de estados na camada EJB. Tratamento de erros desajeitado. Tendo em vista que o framework de Commands genrico pode-se gerar apenas uma CommandException a partir de um Command. Isto significa que as excees da aplicao, como NoMoneyInAccountException, precisam ser apanhadas e envolvidas em uma CommandException. Os clientes precisam ento buscar excees particulares dentro do objeto Command. Como as excees no so declaradas explicitamente, os clientes perdem o benefcio da checagem do tratamento de excees em tempo de compilao. Comandos podem se tornar impossveis de gerenciar em projetos grandes. Um projeto grande pode explodir com milhares de Commands, muitos dos quais tm partes de lgica de negcio duplicadas, especialmente quando vrias equipes de projeto esto usando o mesmo modelo de domnio como fundo. Isto dificulta a manuteno da camada de lgica de negcio, em oposio ao padro Session Faade, em que os casos de uso so implementados como mtodos de Session Beans, satisfatoriamente agrupados em um pequeno nmero de Session Beans. Esta proliferao de classes pode ser um problema srio em projetos grandes. ejb-jar do CommandServer acoplado a Command Beans e outros EJBs. Como os Command Beans so executados dentro do ambiente dos Session Beans CommandServer, as classes de Command Beans precisam ser distribudas com o Session Bean CommandServer (no mesmo ejb-jar ou EAR) para que os Command Beans sejam desserializados e executados. Isto significa que toda vez que um Command Bean alterado, o EAR ou ejb-jar do Session Bean

38

CAPTULO 1

CommandServer precisar ser redistribudo (de forma que os carregadores de classe dos CommandServers possam ler as novas verses de todos os Commands includos) para testar as alteraes, ou reiniciado completamente, se o seu servidor de aplicao no suportar distribuio a quente. Alm disso, os Command Beans precisam ter visibilidade de qualquer home, remota ou no, e interfaces locais que possam usar na sua lgica de negcio. Isto requer que o CommandServer seja colocado no mesmo EAR dos outros EJBs acessados por qualquer um dos seus Command Beans ou que as interfaces dos EJBs acessados sejam colocadas no mesmo pacote com o ejb-jar do CommandServer. Os padres Command e Session Faade proporcionam dois benefcios importantes: agem como uma fachada e so executados em um ciclo da rede. Uma vantagem importante do padro Command sobre o Session Faade que ele desacopla o cliente do EJB, o que pode tambm ser obtido aplicandose o padro Business Delegate em conjunto com o Session Faade. Ento, como o desenvolvedor pode escolher entre um e o outro? til pensar em Commands como Session Beans mais baratos. Eles so mais leves, resultando em um processo de desenvolvimento inicial mais rpido, o que, em contrapartida, pode diminuir a facilidade de manuteno com o passar do tempo.

Padres relacionados
Command (Gamma et al., 1995) Data Transfer HashMap

DATA TRANSFER OBJECT FACTORY


Um sistema J2EE que usa objetos de transferncia de dados (DTOs Data Transfer Objects) descobre que sua camada DTO tende a mudar com freqncia. Como deve ser implementada a lgica de criao e uso de objetos de transferncia de dados para minimizar o impacto de mudanas freqentes na camada DTO sobre o resto do sistema? * * * Os objetos de transferncia de dados tendem a mudar freqentemente. Os DTOs do domnio mudam sempre que os objetos do domnio mudam (acrescentando um novo atributo em um Entity Bean e assim por diante). Os DTOs customizados so apenas depsitos de dados especficos para um determinado caso de uso, servindo para transportar dados atravs de uma rede. Eles podem mudar com a mesma freqncia da viso da apresentao de sua aplicao. Uma aplicao de mdia a grande poderia ter dezenas, at centenas de diferentes objetos de transferncia de dados, cada um dos quais requereria lgica customizada para ser criado. Torna-se, ento, uma questo fundamental como e onde esta lgica deve ser implementada para que se desacople e proteja o resto deste sistema das mudanas nos objetos de transferncia de dados. Uma soluo comum empregada em aplicaes EJB 1.X colocar mtodos getXXXDTO/setXXXDTO diretamente nos Entity Beans. Neste cenrio, o Entity Bean seria responsvel por povoar este objeto de transferncia de dados e por atualizar a si prprio baseado nos atributos do set DTO. O problema desta abordagem que ela acopla fortemente a camada do objeto de transferncia de dados camada de Entity Beans. Isto significa que colocar o cdigo de criao de objetos de transferncia de dados especficos para um caso de uso em um Entity Bean poderia causar srias dependncias entre seus Entity Beans e clientes em aplicaes mdias a grandes. Cada vez que uma pgina Web mudasse e fosse necessria uma viso diferente do modelo de dados, voc teria que acrescentar um novo mtodo a um Entity Bean, recompilar seu Entity Bean e redistribuir suas interfaces remotas para qualquer cliente que as estivesse usando. Espera-se que Entity Beans sejam componentes de negcio reusveis, que possam ser montados separadamente para criar uma aplicao. Para criar componentes de negcio realmente reusveis,

Padres de arquitetura da camada EJB

39

importante manter uma separao rgida entre as lgicas da sua aplicao e de negcio, permitindo que as duas se desenvolvam separadamente. Deve-se encontrar outra soluo para a criao e o uso de Entity Beans, de modo a conseguir desacoplar a lgica relacionada ao DTO dos outros componentes do sistema. Portanto: Coloque a responsabilidade pela criao e pelo uso de objetos de transferncia de dados em uma fbrica de objetos de transferncia de dados. A fbrica de objetos de transferncia de dados separa a lgica relacionada aos objetos de transferncia de dados (parte do domnio da aplicao) dos outros componentes do seu sistema, como Entity Beans (parte do domnio de negcio). Quando novas vises ou diferentes subconjuntos de dados no lado servidor se tornarem necessrios, novos mtodos de criao de DTOs podero ser adicionados a um DTOFactory, em vez de serem colocados em um Entity Bean. Estes novos mtodos iro interagir com a camada de Entity Bean (ou qualquer outra fonte de dados, como conectores, JDBC e outras), chamando mtodos de recuperao e percorrendo relacionamentos conforme necessrio para gerar objetos de transferncia customizados ou de domnio. A vantagem desta abordagem que os prprios Entity Beans no precisam conhecer estas diferentes vises dos seus dados. Na verdade, nenhum cdigo em um Entity Bean precisa ser alterado. Por exemplo, considere uma aplicao automotiva que permita aos usurios navegar por informaes sobre carros e seus fabricantes. Deste modo, a aplicao ter um modelo de domnio que consistir (entre outros) em um Entity Bean Car e um Manufacturer. Essa aplicao ter uma interface de usurio com vrias pginas diferentes que permitam aos usurios navegar por diferentes propriedades dos carros e de seus fabricantes, incluindo diferentes subconjuntos de atributos de um carro (caractersticas do motor, da lataria, do chassi, etc.) e dados espalhados por diversos Entity Beans (informao sobre o carro e seu fabricante, etc.). Estes diversos conjuntos de dados deveriam ser transferidos para o cliente usando DTOs customizados. Entretanto, em vez de colocar os mtodos Java requeridos para criar estes diferentes DTOs em um Entity Bean Car ou Manufacturer, eles seriam colocados em um DTOFactory como o da Figura 1.10. O CarDTOFactory agora se torna um ponto individual onde reside a lgica de DTO especfica para este caso de uso, ajudando a desacoplar os clientes do modelo do domnio. Os Entity Beans no modelo do domnio esto agora livres para ser objetos de domnio, expondo aos clientes apenas os mtodos de negcio, no a lgica de DTO de gets e sets, o que realmente no tem nada a ver com o conceito do negcio incorporado por esse modelo de domnio em particular. H duas maneiras bsicas de implementao do padro DTO Factory, dependendo de o seu cliente ser um Session Bean ou um cliente no EJB, como um servlet. Quando usado por trs de uma fachada de Session Beans, a fbrica de DTO pode ser implementada como uma classe Java simples que

FIGURA 1.10 CarDTOFactory.

40

CAPTULO 1

apenas armazena a lgica de criao e uso de diferentes objetos de transferncia de dados em seus mtodos. Este tipo de fbrica se presta bem ao reuso, porque os objetos de transferncia de dados que ela gera podem ser reusados em diferentes Session Beans e/ou em diferentes projetos. Quando usada a partir de um cliente no EJB, a fbrica de DTO deve ser implementada como um Session Bean sem estado. Uma interao tpica entre este cliente e o objeto de transferncia de dados est delineada na Figura 1.11. Neste caso, um cliente servlet quer obter um DTO customizado chamado CarAndManufacturerDTO e, ento, procura um CarDTOFactory para esse objeto. O CarDTOFactory ento cria e povoa o DTO chamando mtodos get sobre o Entity Bean Car e seu Entity Bean Manufacturer relacionado atravs de suas interfaces locais. Fbricas de objetos de transferncia de dados podem ser usadas para criar facilmente qualquer tipo de DTO. Mesmo hierarquias complexas de Aggregate DTOs (DTOs de domnio que contm outros DTOs de domnio) podem ser criadas para mapear diferentes fatias do modelo de objetos Entity Bean do lado servidor. Pode-se criar hierarquias complexas de objetos de transferncia de dados escrevendo-se explicitamente lgica que saiba como navegar (e copiar) uma fatia de uma hierarquia de Entity Beans que seja especfica para um caso de uso. Estas hierarquias de DTOs podem ser todas criadas inicialmente no servidor e passadas para o cliente em uma chamada de rede. Um benefcio importante que resulta desta prtica que os Entity Beans de nossa aplicao so agora totalmente reusveis. Por exemplo, imagine duas equipes de desenvolvimento separadas em uma corporao trabalhando em aplicaes separadas. Ambas podem reusar os mesmos Entity Beans componentes de negcio (a propsito, um timo exemplo de reuso EJB) usando fbricas de objetos de transferncia de dados separadas. As equipes poderiam obter reuso completo, cada uma mantendo a prpria fbrica de DTO separada, que distribuiria DTOs especficos de casos de usos fatias do estado do Entity Bean independentemente da outra equipe. Cada uma mantendo a prpria fbrica DTO, elas poderiam tambm desenvolver e distribuir as prprias aplicaes completamente independentes uma da outra. Este conceito est ilustrado na Figura 1.12. Perceba que o padro Data Transfer Object Factory no significa a criao de uma fbrica de DTO para cada classe de Entity Bean. Por exemplo, voc no precisa necessariamente criar um CarDTOFactory para um Entity Bean Car. Isto resultaria na exploso das fbricas VO. Onde os requisitos permitirem, pode ser mais simples e direto criar uma fbrica DTO para um conjunto inteiro de Entity Beans e/ou outras fontes de dados do lado servidor. As fbricas DTO fornecem uma maneira de ler dados do servidor, mas e a atualizao dos dados? Tcnicas similares s usadas na leitura de dados do lado servidor podem ser usadas para

FIGURA 1.11 Uso de uma fbrica de Car DTO como um Session Bean.

Padres de arquitetura da camada EJB

41

FIGURA 1.12 Obteno de reuso de Entity Beans com fbricas de objetos de transferncia de dados.

atualizar dados. Isto quer dizer que os clientes podem passar um DTO de domnio ou um DTO customizado para o servidor, no qual ele pode, por sua vez, desempenhar operaes de criao, leitura, atualizao e remoo (operaes CRUD Create, Read, Update e Delete) em Entity Beans ou em outros depsitos de dados no lado servidor. Para os DTOs de domnio (os quais so normalmente feitos mutveis), o cliente executar suas atualizaes localmente sobre um DTO e ento atualizar o servidor passando um DTO de domnio para um mtodo updateXXXEntity em uma fbrica de DTO, a qual copiaria os atributos do DTO para o Entity Bean apropriado, usando mtodos set de granularidade fina na interface local do Entity Bean. Os clientes podem, de forma semelhante, criar Entity Beans povoando localmente um DTO de domnio e o passando para um mtodo createXXXEntity na fbrica. Usando o exemplo anterior, se o administrador da aplicao quisesse atualizar um carro ou fabricante em particular, estas atualizaes seriam feitas em interfaces de usurio separadas (uma para o carro e uma para o fabricante). As atualizaes seriam executadas e seria enviado um DTO de domnio Car ou um Manufacturer de volta para o servidor para atualizao em uma nica transao, conforme mostrado na Figura 1.13. Para executar qualquer tipo de atualizao maior que a atualizao CRUD dos objetos do domnio, o servidor deve ser atualizado, passando DTOs customizados para a fachada de sesso/mensagem. Lembre-se que a fachada deve conter toda a lgica de negcio necessria para executar casos de uso em uma aplicao, como realizar uma encomenda no Amazon ou transferir fundos em um banco. Para estes tipos de operaes, o cliente normalmente criar um DTO customizado que contenha todos os dados necessrios para executar a atualizao e passar este DTO para a fachada, a qual por sua vez ir criar, atualizar ou remover qualquer nmero de recursos no lado servidor. As vantagens da abordagem da fbrica de objetos de transferncia de dados so muitas: Facilita a manuteno. Separando a lgica de sua aplicao (casos de uso) e seu modelo de objetos de dados (Entity Beans), ambos podem evoluir isoladadamente. Os Entity Beans no precisaro mais ser alterados e recompilados quando as necessidades do cliente mudarem. Encoraja o reuso de Entity Beans. Os Entity Beans podem ser reusados por outros projetos, j que diferentes fbricas DTO podem ser escritas para satisfazer s necessidades de diferentes aplicaes. Permite a criao de diagramas complexos de DTOs. Escrevendo a lgica de criao de DTOs logo no incio, os desenvolvedores podem criar diagramas/hierarquias complexos(as) de DTOs que podem ser usados(as) para transferir os dados de hierarquias complexas de Entity Beans contendo relacionamentos um para um, um para muitos, muitos para muitos e cclicos, alm de combinaes desses relacionamentos. Isto fornece aos clientes maior controle sobre que partes dos dados dos Entity Beans eles precisam mostrar. Para clien-

42

CAPTULO 1

FIGURA 1.13 Atualizao de dados usando uma fbrica de objetos de transferncia de dados.

tes no Web, como aplicaes Java e applets, a habilidade de obter dados no tabulares especialmente importante. Melhora o desempenho. Quando a fbrica DTO usada como uma fachada de sesso, os atributos de diversos Entity Beans podem ser passados para o cliente em apenas uma chamada de rede. O padro Data Transfer Object Factory pode construir sistemas flexveis e passveis de manuteno, fornecendo um mtodo simples e consistente para criar complexos objetos de transferncia de dados e pass-los ao cliente em uma grande chamada de rede, sem causar dependncias entre os objetos de transferncia de dados e outros componentes em um sistema J2EE.

Padres relacionados
Session Faade Data Transfer Object Value Object Assembler (Alur et al., 2001)

GENERIC ATTRIBUTE ACCESS


O cliente de um Entity Bean precisa acessar os atributos deste. Como o cliente de um Entity Bean pode acessar e manipular eficientemente os atributos deste de um modo genrico e em grandes quantidades? * * * Na prtica comum, os Entity Beans so acessados por meio de mtodos get/set de sua interface local (para Entity Beans escritos em EJB 2.X em diante) ou por meio de grandes objetos de transfern-

Padres de arquitetura da camada EJB

43

cia de dados em interfaces remotas (para Entity Beans EJB 1.X). Com o primeiro, os mtodos na fachada de sesso ou na fbrica de objetos de transferncia de dados interagem com os Entity Beans, chamando diversos mtodos de gravao e leitura de granularidade fina para acessar e manipular atributos, conforme requerido por cada caso de uso. Usando o segundo modo, os objetos de transferncia de dados so usados para minimizar as chamadas de rede associadas comunicao com as interfaces remotas. O uso de DTOs como mecanismo de manipulao de Entity Beans um padro comum de otimizao da comunicao com Entity Beans EJB 1.X. A perda acarretada pelo uso de DTOs para acessar EJB 1.X Entity Beans a diminuio da capacidade de manuteno da camada dos Entity Beans (veja o padro DTO Factory). Com o advento do EJB 2.0, as interfaces locais permitiram a extrao da lgica de criao e uso do DTO para uma fbrica de objetos de transferncia de dados. Neste caso, a fbrica de DTOs interage com um Entity Bean por meio de gets/sets de granularidade fina na interface local, atenuando alguns problemas do uso de DTOs. Infelizmente, os Entity Beans EJB 1.X no tm interfaces locais. Como conseqncia, a lgica de criao/uso de DTOs no pode ser extrada dos Entity Beans para uma fbrica de DTOs (porque ruim para o desempenho uma fbrica de DTOs fazer diversas chamadas de granularidade fina para a interface remota de um Entity Bean). necessrio algum outro mecanismo que permita acesso a uma grande quantidade de dados do Entity Bean por meio da interface remota, sem se misturar com a lgica de criao/uso do DTO. Mesmo para interfaces locais, em alguns casos, expor diversos mtodos get/set de granularidade fina no uma boa idia: No escala bem de pequenos para grandes Entity Beans. Imagine um Entity Bean de aes/ttulos em uma aplicao financeira. Esse Entity Bean poderia bem ter duzentos atributos. Escrever e expor mtodos de leitura e gravao para todos esses atributos poderia resultar em um pesadelo de codificao tediosa e em uma exploso no tamanho da interface. Resulta em clientes altamente acoplados e com cdigo explcito. Os clientes Entity Bean (como a fachada de sesso) precisam ser altamente acoplados interface do Entity Bean, tornando-a sensvel a quaisquer mudanas que possam ocorrer como a adio ou remoo de um atributo. O ponto a considerar a necessidade de algum outro mecanismo para acessar dados de Entity Beans, que possa permitir a uma fbrica de DTOs usar a interface remota para pegar dinamicamente subconjuntos diferentes do estado do Entity Bean em uma grande chamada de rede e tambm ajudar a desacoplar clientes Entity Bean dos acessadores de atributos do Entity Bean, ao usar uma interface local. Portanto: Abstraia a lgica de acesso a atributos de um Entity Bean em uma interface de acesso de atributos genrica, usando HashMaps para passar atributos tipo valor-chave para Entity Beans e destes. A interface de acesso de atributos implementada pelos Entity Beans na interface local ou remota e tem esta aparncia:
public interface AttributeAccess { public Map getAttributes (Collection keysOfAttributes); public Map getAllAttributes (); public void setAttributes (Map keyAndValuePairs); }

AttributeAccess fornece uma interface genrica que permite que conjuntos de dados arbitrrios sejam lidos ou gravados em um Entity Bean dinamicamente. A interface permite a Entity Beans EJB 1.X usar uma fbrica de DTOs para extrair a lgica de criao de DTOs e otimizar as chamadas remotas, bem como permitir a Entity Beans EJB 2.X simplificar suas interfaces locais, eliminando a necessidade de mtodos get/set de granularidade fina. A nica dependncia entre o cliente e o cdigo do

44

CAPTULO 1

Entity Bean so as convenes de nomes colocadas nas chaves usadas para identificar os atributos, descritas mais adiante neste padro. A fachada de sesso ou a fbrica de DTOs pode acessar os atributos de um Entity Bean pela interface de acesso aos atributos. A Figura 1.14 ilustra um caso tpico: um cliente est interessado em juntar um subconjunto dos dados de um Entity Bean Car relacionados a seu motor. Ele chama o mtodo getCarEngineData na fachada de sesso, o qual, por sua vez, pede a um Entity Bean os atributos exatos que fazem parte do motor do carro, primeiramente criando um conjunto que inclui os valores-chave dos atributos de interesse (potncia, volume e outros) e ento passando este conjunto ao mtodo getAttributes(conjunto) no Entity Bean, o qual ir retornar um HashMap com este subconjunto exato. Aps receber o HashMap povoado do Entity Bean Car, o Session Bean pode: 1. Retornar o HashMap para um cliente remoto. Neste caso, o Session Bean usa o HashMap como um continer serializvel para transferir dados por meio da rede (conforme descrito no padro Data Transfer HashMap no Captulo 2). 2. Converter o HashMap em um DTO e retorn-lo. Sendo uma fbrica de DTOs, o Session Bean pode extrair os valores do HashMap e adicion-los a um objeto de transferncia de dados, retornando o DTO para o cliente. A opo depende do desenvolvedor. Como um mecanismo de transferncia de dados, os HashMaps apresentam muitas vantagens sobre os objetos de transferncia de dados (como descrito no padro Data Transfer HashMap), mas, em contrapartida, aumenta significativamente a complexidade. Se a interface de acesso a atributos for usada por trs de uma fbrica de DTOs, as dependncias entre nomes de chaves/valores podem ser mantidas no servidor, onde, de qualquer maneira, os Session Beans precisam estar cientes dos Entity Beans. Usando a interface de acesso a atributos, um Session Bean pode, portanto, decidir dinamicamente de quais subconjuntos de dados do Entity Bean ele precisa em tempo de execuo, eliminando a necessidade de programao manual em tempo de desenho dos objetos de transferncia de dados. Do mesmo modo que a prpria interface, a implementao da interface de acesso a atributos genrica. Sob Bean-Managed Persistence (BMP Persistncia Gerenciada por Beans), o Entity Bean pode ser mais simplificado, armazenando todos os seus atributos em um HashMap interno e privado, em vez de depender, de codificao explcita dos atributos como geralmente ocorre. Para Entity Beans grandes, esta otimizao pode simplificar muito o cdigo do Entity Bean. Usando este HashMap inter-

FIGURA 1.14 Uso da interface de acesso a atributos.

Padres de arquitetura da camada EJB

45

no, a implementao dos mtodos no AttributeAccess se torna, portanto, completamente genrica e reusvel por todos os Entity Beans BMP .
private java.util.HashMap attributes; /** * Retorna pares de chave/valor de atributos de Entity Beans * @return java.util.Map */ public Map getAllAttributes () { return (HashMap)attributes.clone (); } /** * Usado pelos clientes para especificar os atributos nos quais eles esto interessados * @return java.util.Map * @param keysofAttributes o nome dos atributos nos quais o cliente est * interessado */ public Map getAttributes (Collection keysofAttributes) { Iterator keys = keysofAttributes.iterator (); Object aKey = null; HashMap aMap = new HashMap (); while ( key.hasNext () ) { aKey = keys.next (); aMap.put ( aKey, this.attributes.get ( aKey) ); } //o map agora tem todos os dados requisitados return aMap; }

/** * Usado pelos clientes para atualizar atributos particulares no Entity Bean * @param keyValuePairs java.util.Map */ public void setAttributes (Map keyValuePairs) { Iterator entries = keyValuePairs.entrySet ().iterator (); Map.Entry anEntry = null; while ( entries.hasNext ()) { anEntry = (Map.Entry)entries.next (); this.attributes.put (anEntry.getKey (), anEntry.getValue ()); } }

46

CAPTULO 1

No CMP (Container-Managed Persistence), no possvel usar um mapa interno de atributos, j que a implementao das classes do Entity Bean abstrada atrs de mtodos get e set gerados por um continer. Quando no for possvel usar um mapa interno, a interface de acesso a atributos pode ser implementada genericamente usando a API de Reflexo Java. Isto significa que, no setAttributes, a reflexo pode ser executada sobre o valor-chave dos atributos que o cliente queira configurar. Especificamente, se o valor-chave for XXX, a implementao de setAttribute tentar chamar setXXX (...) do Entity Bean. Do mesmo modo, no mtodo getAttributes, a reflexo pode ser usada para encontrar todos os mtodos get em um Entity Bean, cham-los e povoar um mapa para o cliente. Se o desenvolvedor preferir no usar a API de Reflexo, a implementao do mtodo Attribute Access no poder ser feita genericamente para CMP . O desenvolvedor precisar entrelaar sua implementao de Attribute Access como declaraes IF que chamem mtodos get/set explcitos no Entity Bean, dependendo do valor-chave. Para tornar o cdigo da implementao de Attribute Access reusvel por todos os Entity Beans, pode-se usar uma superclasse para implementar os mtodos da interface, que so completamente genricos, se se usar o mtodo reflexivo ou o mapa interno de atributos. Todos os Entity Beans que quiserem fazer uso dos servios do Attribute Access precisam apenas ser suas subclasses. Desta forma, expem automaticamente esta interface unificada para seus atributos, sem necessidade de cdigo extra. A pea final do quebra-cabeas como nomear as chaves que identificam os atributos de um Entity Bean. No apenas os atributos precisam ser identificados por uma chave, mas a lgica que acessa o Entity Bean por meio da interface de acesso a atributos e o prprio Entity Bean precisam concordar com as convenes de nomeaes. necessrio algum tipo de contrato entre o cliente e o servidor. Diversas possibilidades so discutidas: Estabelea uma conveno de nomeaes consistente e bem documentada. O cliente e o Entity Bean podem concordar uma conveno de nomeaes bem documentada e consistente para os atributos. Para um Entity Bean Account, com.bank.Account.accountName, ou simplesmente accountName seriam exemplos de convenes consistentes. A desvantagem desta abordagem que o contrato existe apenas nas mentes dos desenvolvedores e no papel. fcil, durante o desenvolvimento, errar o nome do atributo, resultando em erros de desenvolvimento custosos e difceis de encontrar. Defina variveis do tipo static final na interface local ou remota do Entity Bean. Um cliente de Entity Bean pode fazer chamadas a ele usando referncias a variveis static final contendo a chave correta para obter um atributo. Por exemplo, para recuperar os atributos de um Entity Bean Employee, o Session Bean poderia usar o seguinte cdigo:
//Solicitar os atributos pessoais do empregado Collection aCollection = new ArrayList (); aCollection.add (Employee.NAME); aCollection.add (Employee.EMAIL); aCollection.add(Employee.SEX); aCollection.add(Employee.SSN); Map aMap = employee.getAttributes (aCollection);

em que a interface local do Entity Bean contm as seguintes definies:


public interface Employee extends EJBLocalObject, AttributeAccess { //J que os atributos esto armazenados em um hashmap no Entity Bean, //precisamos de um lugar central para armazenar as 'chaves' usadas para //referenciar atributos, de modo que os clientes e o Entity Bean no

Padres de arquitetura da camada EJB

47

//precisem ser codificados explicitamente com conhecimento das //strings-chave dos atributos public final static String ID = "EMPLOYEEID"; public final static String NAME = "NAME"; public final static String EMAIL = "EMAIL"; public final static String AGE = "AGE"; public final static String SSN = "SSN"; public final static String SEX = "SEX"; ... }

Esta abordagem funciona muito bem com a da fbrica de DTOs, em que um Session Bean busca seus atributos diretamente no Entity Bean, com a inteno de retornar um objeto de transferncia de dados codificado explicitamente para o cliente, em vez de um HashMap. Neste caso, apenas o Session Bean e o Entity Bean precisam concordar os nomes das chaves dos atributos, tornando a interface local/remota um bom local para localizar os nomes dos atributos. Esta abordagem falha ao usar o padro Data Transfer HashMap, pois o cliente tambm precisa conhecer os nomes dos valores-chave, mas no tem acesso interface local/remota do Entity Bean. Classe compartilhada com variveis do tipo static final. Aqui, podemos criar uma classe compartilhada pelas classes do cliente e pelas classes do servidor, o que usado para encapsular as strings utilizadas para povoar e ler strings de um HashMap por trs de uma varivel do tipo static final codificada explicitamente, acessvel para o cliente e para o servidor. Por exemplo, um cliente buscaria um hashmap para um atributo da seguinte forma:
accountMap.get (Names.ACCOUNTBALANCE);

Assim, a classe compartilhada chamada Names teria o aspecto:


public class Names { public final static String ACCOUNTBALANCE = "BALANCE"; ... }

Uma desvantagem desse mtodo que, se os mapeamentos das chaves precisassem ser atualizados ou receber acrscimos, a nova classe precisaria ser redistribuda para o cliente e o servidor (e seus JVM precisariam, ser assim reinicializados). Coloque o contrato do Attribute em uma rvore JNDI. Nesta abordagem, um nico exemplar de cada tipo mantido, colocando-se uma classe contendo as chaves em uma rvore JNDI, acessvel para o cliente e para o servidor. Os cdigos do cliente e o do servidor no precisariam ser recompilados ou reinicializados quando as chaves sofressem alterao/atualizao, pois um objeto central em uma rvore JNDI conteria sempre a cpia mais recente das chaves. A desvantagem desta soluo o overhead causado ao obter o contrato da rvore JNDI cada vez que os valores das chaves forem requeridos. O padro Generic Attribute Access tem muitas vantagens: Uma interface para todos os Entity Beans. Os clientes de Entity Beans podem manipul-los consistentemente por meio da interface de acesso aos atributos, simplificando o cdigo do cliente. Os Entity Beans tambm so simplificados, porque o acesso aos atributos pode ser encapsulado em uma superclasse. Escala bem em Entity Beans grandes. Se um Entity Bean tiver vinte ou dois mil atributos, a lgica de acesso aos atributos ser simplificada para apenas algumas linhas.

48

CAPTULO 1

Baixo custo de manuteno no decorrer do tempo. possvel criar novas vises dos dados no lado servidor sem necessidade de qualquer programao no lado servidor. Os clientes podem decidir dinamicamente que atributos mostrar. Permite a adio dinmica de atributos em tempo de execuo. Ao usar BMP , este padro pode facilmente ser estendido para permitir a capacidade de adio e remoo dinmica de atributos de um Entity Bean. Isto pode ser obtido acrescentando-se um mtodo addAttribute e um removeAttribute interface, os quais simplesmente executam operaes no atributo HashMap. Como acontece com todo padro, usar o Generic Attribute Access tem suas desvantagens: Overhead adicional por chamada de mtodo. Para cada chamada de atributo, os clientes devem usar uma chave de atributo para identific-lo. Finalmente, os atributos precisam sofrer converso para seus tipos apropriados aps terem sido extrados do objeto HashMap. Necessidade de manuteno de um contrato para chaves de atributos. Como as strings requerem atributos, os clientes precisam se lembrar das strings-chave usadas para identificar os atributos. Definir um contrato de atributo-chave (discutido anteriormente neste padro) pode aliviar estas dependncias. Perda de checagem de tipificao/tempo de compilao. Quando usamos DTOs, os valores passados por gets ou sets so sempre do tipo correto. Quaisquer erros seriam passados em tempo de compilao. Ao utilizarmos o padro Generic Attribute Access, o acesso aos atributos deve ser gerenciado pelo cliente em tempo de execuo por meio da converso de objetos para seus tipos corretos e da associao dos tipos corretos dos atributos chave correta. De um modo geral, o padro Generic Attribute Access fornece um mtodo genrico de gerenciamento do estado dos Entity Beans, eliminando a grande quantidade de cdigo repetitivo associado ao acesso a dados de Entity Beans especficos do domnio.

Padres relacionados
Property Container (Carey et al., 2000) Data Transfer HashMap

BUSINESS INTERFACE
A especificao EJB determina que uma classe Enterprise Bean fornea uma implementao de todos os mtodos declarados nas interfaces locais ou remotas, mas o Bean no pode implementar estas interfaces diretamente. Como as inconsistncias entre os mtodos das interfaces locais e remotas e a implementao do Enterprise Bean podem ser descobertas em tempo de compilao? * * * Um dos erros mais comuns durante o processo de desenvolvimento EJB a falta de consistncia entre as definies dos mtodos de negcio nas interfaces remotas ou locais e as implementaes na classe Enterprise Bean. A especificao EJB requer que o Enterprise Bean implemente de modo adequado todas as assinaturas de mtodos de negcio definidas na interface local/remota, mas no fornece uma maneira automtica de deteco de problemas em tempo de compilao. Muitos tipos de erros podem acontecer a partir deste desacoplamento entre a definio da interface e a implementao, incluindo erros de nomes de mtodos, tipos de parmetros, excees, parmetros inconsistentes e outros. Como resultado, estes tipos de erros no podem ser detectados em tempo de compilao, e o

Padres de arquitetura da camada EJB

49

desenvolvedor EJB deve realizar manualmente a manuteno da consistncia entre a definio da interface e a implementao do Bean. Os erros podem ser detectados somente com a ferramenta de ps-compilao proprietria do seu vendedor de servidor EJB. Essas ferramentas so normalmente usadas para testar a conformidade de classes Java compiladas especificao EJB antes de empacot-las e distribu-las. Tais ferramentas de ps-compilao normalmente so lentas e difceis de usar, sendo menos viveis para prticas de compilao incremental que os desenvolvedores muitas vezes usam para detectar os erros logo no incio. Como resultado, os erros de desenvolvimento so apanhados mais tarde durante este processo. Uma soluo seria fazer o Enterprise Bean implementar diretamente a interface local ou remota na classe Bean, o que foraria a consistncia entre a definio de mtodos e suas implementaes, usando qualquer compilador Java padro. Infelizmente, a especificao EJB no recomenda esta prtica, e com um bom motivo: a interface remota estende a interface javax.ejb.EJBObject e a interface local implementa a interface javax.EJBLocalObject, conforme mostrado na Figura 1.15. Essas interfaces definem mtodos extras (isIdentical, getPrimaryKey, remove, etc.), que devem ser implementados pelos stubs EJBObject e EJBLocalObject, no pela classe Enterprise Bean. Para fazer seu Bean compilar, voc teria que abarrotar a classe Enterprise Bean escrevendo implementaes vazias destes mtodos extras. Alm disso, se ela implementasse diretamente a interface local ou remota, o Bean poderia ser convertido diretamente para uma dessas interfaces, permitindo ao desenvolvedor passar uma instncia de this para um cliente. Este comportamento no permitido pela especificao EJB. Para passar uma referncia, o Bean precisa primeiro obter uma referncia para si prprio, chamando getEJBObject ou getEJBLocalObject da interface SessionContext ou EntityContext. Os desenvolvedores EJB no devem implementar interfaces locais ou remotas diretamente em sua classe Enterprise Bean, mas precisam de um mecanismo que permita uma confirmao em tempo de compilao da consistncia entre as definies de mtodos nas interfaces remota e local e as implementaes na classe Bean.

FIGURA 1.15 Interfaces EJBObject e EJBLocalObject.

50

CAPTULO 1

Portanto: Crie uma superinterface, chamada interface de negcio, que define todos os mtodos de negcio. Deixe tanto a interface local/remota quanto a classe Enterprise Bean implementar esta interface, forando checagens de consistncia em tempo de compilao. Interface de negcio uma interface Java simples que define as assinaturas de mtodo para todos os mtodos de negcio que um Enterprise Bean decidir expor. implementada pela interface local ou remota e pela classe Enterprise Bean, conforme mostrado na Figura 1.16. Criando esta superinterface, erros de consistncia entre as definies de assinaturas de mtodo na interface local/remota, bem como a classe Enterprise Bean, podem ser apanhados em tempo de compilao. A interface de negcio no implementa javax.ejb.EJBObject ou javax.ejb.EJBLocalObject, de modo que o desenvolvedor da classe Bean no tem de implementar mtodos vazios. Alm disso, o desenvolvedor no pode converter a classe Bean diretamente para sua interface local ou remota, o que evita que ele passe this para seus clientes. O padro Business Interface difere ligeiramente, dependendo de o Enterprise Bean expor seus mtodos de negcio na interface local ou remota. Se o Entity Bean expuser a interface remota, todas as assinaturas de mtodo na interface de negcio precisaro gerar java.rmi.RemoteException (mas no precisaro estender java.rmi.Remote). Observe que as implementaes de mtodos na classe Enterprise Bean no devem gerar RemoteException: isso foi condenado pela especificao EJB. Em vez disso, os

FIGURA 1.16 Interface de negcio para Beans locais e remotos.

Padres de arquitetura da camada EJB

51

mtodos de negcio podem gerar EJBException de dentro do corpo de um mtodo sem declar-lo na clusula throws, visto que EJBException uma subclasse de RuntimeException. Ao usar a interface de negcio com uma interface local, aquela no precisa implementar qualquer outra interface, e as assinaturas dos mtodos de negcio podem ser escritas sem quaisquer regras especiais. H um efeito colateral perigoso no uso do padro Business Interface: Para mtodos cujos valores de retorno so a interface local/remota do prprio Bean, implementar a interface de negcio permite ao desenvolvedor do Bean retornar this sem que seja detectado qualquer problema em tempo de compilao. Isto possvel porque tanto a classe Bean quanto a interface local/remota implementam a interface de negcio. Retornar this sempre pego em tempo de compilao quando o padro Business Interface no usado (j que a classe Bean no implementa a interface local/remota). Assim, os desenvolvedores de Beans que usam um padro de interface de negcio devem redobrar a ateno para no retornar this ou erros imprevisveis em tempo de execuo. O padro Business Interface comum no desenvolvimento EJB. Ele permite aos desenvolvedores apanhar erros comuns de programao em tempo de compilao, assegurando a consistncia entre a definio e a implementao de mtodos de negcio.

Você também pode gostar