Você está na página 1de 5

Design Patterns Fundamentais do J2EE

Fundo da Computao www.fundao.pro.br Maro/2003

Aplicaes empresariais so complexas, isto um fato. Diariamente desenvolvedores, arquitetos, gerentes de projeto e usurios so forados a lidar com estruturas de dados complexas, alteraes em regras de negcio, mudanas de necessidades dos usurios e novas tecnologias. Naturalmente, os desenvolvedores geralmente tm menos tempo e menos recursos do que precisariam (ou gostariam) para enfrentar tudo isso. Existem vrias formas possveis de tratar tal complexidade, mas todas podem ser agrupadas em dois princpios: utilizar abordagens comprovadamente funcionais e antecipar necessidades futuras. Em ambos os casos, existem tcnicas comuns que transcende um sistema individual. Essas tcnicas so conhecidas como design patterns (para saber mais veja Fontes abaixo). Esses patterns podem ser usados repetidas vezes, facilitando a incorporao da experincia de desenvolvimentos anteriores em novos projetos. Patterns tambm fornecem uma linguagem comum para a discusso de arquitetura de software em um nvel mais elevado (apenas dizer que um sistema implementa o pattern factory, por exemplo, pode comunicar uma deciso de projeto muito mais rapidamente e mais precisamente do que uma explicao complexa, assumindo que ambos os lados saibam o que o padro factory. Com a utilizao cada vez maior da linguagem Java e principalmente de toda a plataforma J2EE os design patterns tm se tornado mais populares, uma vez que para construir uma aplicao de grande porte utilizando J2EE imprescindvel a utilizao de patterns adequados. Existem muitos patterns para J2EE. Neste texto falaremos de apenas quatro deles, que tm por objetivo aumentar a modularidade e a escalabilidade das aplicaes J2EE. Para saber mais sobre os design patterns do J2EE adquira o livro Core J2EE Patterns.

Camadas da Aplicao
Aplicaes empresariais modernas geralmente mantm no mnimo trs camadas: um cliente, um servidor middleware e um banco de dados. No mundo do J2EE, existem geralmente quatro camadas: um cliente, uma aplicao Web construda ou com servlets Java ou com JavaServer pages (JSP), uma camada de lgica de negcio construda em Enterprise JavaBeans (EJB) e uma camada de persistncia que acessa um banco de dados relacional. Projetos em multi-camadas resolvem vrios problemas, mas tambm podem criar alguns outros. Separar interface do usurio, lgica de negcio e dados da aplicao torna o projeto como um todo mais fcil de ser compreendido e permite que diferentes equipes trabalhem em paralelo em cima de diferentes componentes, mas h um lado ruim: aumenta o overhead de comunicao entre as camadas. A plataforma J2EE basicamente um modelo de aplicao distribudo em multi-camadas no qual a lgica da aplicao dividida em componentes de acordo com sua funo. Isto permite que vrios componentes da aplicao que compem uma aplicao J2EE sejam instalados em mquinas diferentes. Contudo, se no tomar o devido cuidado com o J2EE ou qualquer outra arquitetura multi-camadas, voc acabar com um sistema que muitas vezes mais lento do que um sistema de duas camadas. Projetos em multi-camadas possuem mais componentes para serem monitorados e o sucesso de muitos projetos em multi-camadas se enforcam ao tentar dividir as tarefas em componentes apropriados e ao organizar apropriadamente os resultados. Os patterns a seguir ajudaro voc a melhorar a performance de seus sistemas em multi-camadas e torn-los mais fceis de se manter ao reduzir a complexidade. Como todos eles esto relacionados ao particionamento da aplicao, esses so patterns essenciais para quase todas as aplicaes J2EE e altamente relevantes para todos os desenvolvedores. O pattern Model-View-Controller (MVC) refora um projeto modular e de fcil manuteno e fora a separao de camadas. O session faade organiza a lgica de negcio para o cliente. O Data Access Object (DAO) fornece uma interface flexvel entre a lgica de negcio e as fontes de dados reais. Finalmente, o Data Transfer Object (DTO), tambm conhecido como um value object, facilita a comunicao entre as camadas.

Model-View-Controller
O design pattern MVC permite que voc separe o modelo de dados das vrias formas que o dado pode ser acessado e manipulado. Um sistema MVC dividido em um modelo de dados, um conjunto de vises e um Pgina 1

conjunto de controladores. As vises fornecem a interface do usurio e, em uma aplicao padro, consistem de JSP. O controlador geralmente implementado como um ou mais servlets Java. O modelo consiste de ou EJB ou cdigo que fornece acesso direto ao banco de dados relacional. MVC til principalmente para aplicaes grandes e distribudas onde dados idnticos so visualizados e manipulados de formas variadas. Como o MVC facilita a diviso de trabalho por conjuntos de habilidades, este pattern bastante adequado para empresas de desenvolvimento que suportam desenvolvimento modular e concorrente com muitos desenvolvedores. Promovendo a portabilidade de interfaces e do back-end, o pattern MVC tambm torna fcil testar e manter suas aplicaes. A chave para o MVC a separao de responsabilidades. As vises podem usar o modelo de dados para exibir resultados, mas elas no so responsveis por atualizar o banco de dados. Os controladores so responsveis por selecionar uma viso apropriada e por fazer alteraes no modelo de dados. O modelo, por sua vez, responsvel por representar os dados base da aplicao. Algumas vezes o modelo de dados tambm incluir a lgica de negcio (as regras para manipular os dados de negcio), e algumas vezes a lgica de negcio existir na camada do controlador. Na verdade existem quatro componentes em uma aplicao MVC, no trs, j que o cliente uma parte integrante de toda a operao. O cliente envia uma requisio para o servlet, que interage com o modelo de dados para efetuar a ao requisitada pelo cliente. O controlador ento passa informaes para uma viso, que as formata de acordo com as necessidades do cliente. Dependendo dos tipos de clientes suportados, uma atividade pode ter muitas vises. Desacoplar as vises do processo de requisio torna mais fcil criar novas vises para novos formatos. Uma aplicao poderia apresentar uma interface HTML e depois adicionar vises WML (para dispositivos wireless) e vises XML (para Web services) futuramente. A melhor forma de ver o MVC em ao olhar para algum cdigo. Este exemplo simples inclui um servlet controlador, um modelo de dados EJB e uma viso JSP. O cliente faz uma requisio para o servlet, pedindo para ele criar uma nova conta de cliente. O servlet cria a nova entidade EJB para o cliente e passa o objeto resultante para o arquivo JSP.

ClientController.java package exemplo; import import import import import javax.servlet.http.*; javax.servlet.*; javax.naming.*; java.util.*; java.io.IOException;

public class ClienteController extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { try { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.evermind.server.rmi.RMIInitialContextFactory"); env.put(Context.SECURITY_PRINCIPAL, "admin"); env.put(Context.SECURITY_CREDENTIALS, "welcome"); env.put(Context.PROVIDER_URL, "ormi://localhost:23892/current-workspaceapp"); Context ctx = new InitialContext(env); ClienteEJBHome clienteEJBHome = (ClienteEJBHome)ctx.lookup("ClienteEJB"); ClienteEJB clienteEJB; clienteEJB = clienteEJBHome.create(); clienteEJB.setName(req.getParameter("_NomeDoNovoCliente")); req.setAttribute("cliente", clienteEJB); req.getRequestDispatcher("/cliente.jsp").forward(req, res);

Pgina 2

} catch(Throwable ex) { req.setAttribute("Mensagem de Erro", "Erro do EJB: " + ex.getMessage()); req.getRequestDispatcher("/error.jsp").forward(req, res); } }

}
ClientEJB.java package exemplo; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface ClienteEJB extends EJBObject { String getNome() throws RemoteException; void setNome(String novoNome) throws RemoteException; String getCidade() throws RemoteException; void setCidade(String novaCidade) throws RemoteException; String getEstado() throws RemoteException; void setEstado(String novoEstado) throws RemoteException; Boolean creditoAprovado() throws RemoteException; void setCreditoAprovado(Boolean novaAprovacaoDeCredito) throws RemoteException; }

client.jsp <%@ page contentType="text/html;charset=windows-1252"%> <HTML> <H1>Saudaes, <% exemplo.ClienteEJB cliente = (exemplo.ClienteEJB)request.getAttribute("cliente"); out.println(cliente.getNome()); %> </H1> </BODY> </HTML>

O exemplo mostrado nos cdigos tira vantagem de muitas caractersticas do EJB e da API de Servlets do Java para facilitar a transao entre componentes. O controlador invoca a viso usando um despachador de requisies para encaminhar a requisio do cliente para um arquivo JSP e ajusta os atributos da requisio para passar para frente informaes sobre o sucesso ou a falha de seu processamento. A viso ento tem acesso direto ao EJB, sem ter que carregar ele separadamente ou incluir a lgica para povo-lo.

Session Faade
Criar uma aplicao EJB controlvel requer quebrar a camada do EJB em duas partes. O modelo de dados construdo via entity beans e geralmente corresponde camada de banco de dados base. A lgica de negcio (que em aplicaes antigas poderia ter sido mantida em uma aplicao cliente ou em stored procedures dentro do banco de dados) mantida nos session beans. Em muitas circunstncias, clientes acessaro session beans que efetuaro aes sobre entity beans e retornaro resultados apropriados para a aplicao cliente. Geralmente faz sentido definir session beans por questes de reutilizao; em vez de construir um session bean para a transao "comprar um carro", voc poderia construir beans para carregar clientes, alterar estoque, ou requisitar alguma personalizao fbrica, por exemplo. claro, possvel adicionar lgica de negcio diretamente a um entity bean, mas isto deve ser minimizado. No existe uma boa razo para objetos que representem clientes tenham algum conhecimento relativo a objetos que representam carros, mas se um mtodo buyCar() integrado a um objeto cliente, ento isto exatamente o que Pgina 3

vai acontecer. O objeto cliente fatalmente se tornar carregado de mtodos especializados, tornando o reuso genrico mais difcil. Tirar a lgica de negcio dos entity beans e coloc-la na aplicao cliente tambm problemtico, j que cada aplicao cliente (alm de fornecer uma interface para o usurio) deve incluir todas as regras de negcio para modificar a estrutura do entity bean, e deve ter conhecimento de cada entity bean mesmo que tenha sido invocado remotamente na transao. A separao das camadas cliente e de negcio efetivamente desaparece, e qualquer alterao nas regras de negcio ir requerer a atualizao de todos os clientes. Mesmo com a lgica de negcio distribuda em vrios session beans, ainda h o problema do overhead da rede. Clientes EJB acessam o servidor EJB da rede, e chamadas na rede significam atrasos. Acessar um objeto local sempre muito mais rpido do que acessar um objeto remoto, e cada entity bean ou session bean que um cliente usa resulta em uma outra chamada remota. A soluo empacotar transaes de nvel mais alto em uma session faade. A session faade um session bean que organiza um conjunto de mtodos de negcio relacionados. A session faade responsvel por acessar recursos, atualizar dados e realizar a transao com uma interao limitada com o cliente. O propsito da session faade fornecer uma interface simples e unificada para todos os clientes da aplicao. Os clientes podem usar a session faade como um ponto de entrada nico para os dados e para a funcionalidade de uma aplicao. Centralizando o maior nmero possvel de operaes no servidor, a session faade pode tirar vantagem total do EJB 2.0, incluindo interfaces locais de EJB's. No EJB 2.0, quando um bean interage com um outro bean no mesmo servidor, ele pode acessar aquele bean diretamente chamando os mtodos apropriados, em vez de realizar cada invocao de mtodo atravs da rede. Esta abordagem pode render ganhos de performance substanciais, particularmente em casos onde o bean est interagindo com mltiplos session e entity beans. primeira vista, difcil de dizer o que diferencia uma session faade de um session bean normal. Alm disso, ambos so implementados como session beans, e desta forma, da perspectiva do cliente, parecem a mesma coisa. Uma session faade fornece uma camada de controle para a lgica de negcio de uma aplicao. Uma session faade geralmente fornecer suporte para um ou mais casos de uso relacionados da aplicao, enquanto que um session bean poderia suportar ou um caso de uso ou um componente de um caso de uso. Diferentes aplicaes clientes podem usar diferentes conjuntos de session faades para interagir com o mesmo modelo de dados. Isto faz da session faade um local ideal para tratar de transaes, j que grupos de atividades podem ser facilmente declarados como parte de um nico mtodo de negcio. E ao minimizar as interfaces apresentadas ao cliente, a camada do servidor fica mais fcil de se manter, j que est sujeita a menos dependncias externas. Em aplicaes menores, session faades podem efetivamente agir como um substituto do front-end para os session beans e entity beans que compem o modelo de dados. Quando se desenvolve aplicaes simples, expor todo o modelo de EJBs diretamente para o cliente faz algum sentido; melhor considerar o uso de session faades se existe alguma chance da sua aplicao expandir ou se voc espera que o modelo de dados de backend seja alterado.

Data Access Object


Pense nos recursos que uma aplicao pode precisar acessar. Bancos relacionais so relativamente fceis de se tratar: EJBs CMP (Container-Managed Persistence) podem fazer a maior parte do trabalho para voc, mapeando transparentemente os campos de um EJB para tabelas em um banco de dados base. Mas o que voc deve fazer com relao a armazenamento em disco, arquivos XML, sistemas proprietrios e Web services? Ou para sistemas que utilizam um banco relacional mas no usam EJB totalmente ou usam EJB's BMP (Bean-Managed Persistence)? Ou quando mltiplas aplicaes precisam acessar um modelo de dados? Ou quando os dados vm de uma fonte hoje e de outra amanh? O pattern DAO uma soluo simples para essas questes. Com esta soluo, desenvolvedores implementam um objeto que unicamente responsvel por receber informao de um armazenamento persistente, onde quer que ele esteja. Isto abstrai a viso do dado usada por uma aplicao do layout da tabela, esquema XML ou arquivo em disco. Uma equipe poderia produzir trs objetos DAO por um projeto particular: um para ler o banco de dados, um para ler dos arquivos XML recebidos da Web e um para fornecer dados de teste para serem usados por desenvolvedores trabalhando em outros aspectos do sistema. Se todos os trs objetos so descendentes de uma nica classe abstrata Java que define os vrios mtodos de acesso, os objetos podem ser substitudos na Pgina 4

aplicao final dependendo das necessidades atuais. Os objetos podem tambm ser usados em outros projetos baseados no mesmo modelo. Alm de fornecer flexibilidade extra, um DAO pode ser usado para aumentar a velocidade da camada de apresentao (ou viso) em uma aplicao maior pulando uma camada EJB. Ler diretamente do banco de dados sempre mais rpido do que ir atravs da camada EJB, que tem que ler o banco de qualquer forma. Fazer isto diretamente com a API JDBC (Java Database Conectivity) uma prtica perigosa, j que ela liga o modelo de dados camada de apresentao de tal forma que qualquer alterao na implementao do modelo de dados requer reescrever grandes partes da camada de apresentao, o que geralmente no muito prtico. Ao se utilizar um DAO obtm-se o mximo de velocidade com muito menos esforo de manuteno.

Data Transfer Object


Como mencionamos anteriormente, chamadas de mtodos remotos podem degradar severamente a performance de uma aplicao J2EE. Existem duas formas de reduzir este overhead, ambos trabalham com a minimizao do nmero de conexes com o servidor remoto. J mostramos a session faade, que trabalha tentando manter o maior nmero possvel de chamadas locais para o servidor EJB. A outra abordagem principal, o DTO, pode ser usado quando dados apenas tm que ser transferidos para o cliente. DTOs trabalham coletando conjuntos de informaes relacionadas em um nico objeto. Este objeto pode ser transferido do EJB para o cliente com uma nica chamada remota. Em vez de fazer chamadas separadas para receber nome, endereo e formas de pagamento, o cliente pode receber um objeto contendo tudo em uma nica chamada. J que cada chamada na rede pode adicionar uma aprecivel frao de segundo ao tempo que ela gasta para executar uma atividade, reduzir este overhead geralmente o mais efetivo melhoramento de performance possvel para uma aplicao J2EE. Usando a aplicao anterior, podemos adicionar o suporte a DTO adicionando um mtodo getCliente definio do EJB, que retorna um objeto ClienteDTO. O ClienteDTO um JavaBean simples que inclui propriedades para cada campo do EJB pai ao qual estamos interessados. O cliente pode chamar getCliente() e imediatamente receber um pacote contendo todas as informaes sobre o cliente. Existem muitas formas possveis de implementar um DTO. Uma forma, como j vimos, usar um JavaBean para encapsular sua informao. Esta abordagem permite a checagem de tipos em tempo de compilao e tem a vantagem adicional de ser essencialmente auto-documentvel. Uma outra abordagem comum usar uma implementao do Framework de Colees Java, geralmente um HashMap. Esta abordagem mais flexvel do que escrever um objeto personalizado e no requer a insero de uma arquivo de classe de DTO no cliente. Usar um HashMap, contudo, requer definir um conjunto de chaves antes do tempo e garante que o cliente e o EJB usam as mesmas chaves. HashMaps tambm no permitem checagem de tipo em tempo de compilao, o que pode resultar em erros estranhos e difceis de diagnosticar futuramente.

E Agora?
Os quatro patterns cobertos aqui so apenas o comeo. Alm de vrias variaes e especializaes desses patterns bsicos, voc encontrar muitos outros patterns que podem ser usados para resolver uma grande gama de problemas. A medida que continuar a desenvolver suas aplicaes J2EE, novos patterns e variaes se tornaro evidentes. Ficar de olho nas novas descobertas muito til para projetos futuros.

Fontes
Design Patterns O que so? - http://www2.fundao.pro.br/articles.asp?cod=144 Core J2EE Patterns - http://java.sun.com/blueprints/corej2eepatterns/ TheServerSide - http://www.theserverside.com

Pgina 5

Você também pode gostar