Você está na página 1de 15

Construindo Sistemas Distribuídos Pensando no Reuso dos Padrões

Jaguaraci Batista Silva

Laboratório de Sistemas Distribuídos –Universidade Federal da Bahia (UFBA) Salvador, BA– Brasil.

jaguarac@ufba.br

Resumo. A reutilização de padrões de projeto na construção de outros (e.g. padrões arquiteturais) é um exemplo prático e pode se mostrar eficaz durante a fase de construção de um domínio de aplicação ou nos projetos de design de sistemas. O trabalho enfatiza o reuso e as oportunidades para melhorar o desenvolvimento de sistemas distribuídos através dos padrões de projeto. Para demonstrar o reuso dos padrões de projeto, foi analisada uma aplicação construída a partir dos padrões Java EE (Malks et al, 2003). reutilizando os padrões JEE em conjunto com o Adaptive Comunication Environment (ACE), o Model View Controller (MVC) e mostrados alguns padrões Gof que servem de base para a criação dos padrões da arquitetura JEE.

1. Introdução

Com o surgimento de diversos padrões para implementação de software pouco se comenta sobre a forma de reuso destes. Na tecnologia Java, por exemplo, os padrões mostrados em (Malks et al, 2003) e utilizados durante a construção de um projeto usando a tecnologia Java EE (Sun, 2007), são concebidos re-aproveitando as melhores práticas do Gof (Gamma et al, 1995). A reutilização de padrões de projeto na construção de outros (e.g. padrões arquiteturais) é um exemplo prático e pode se mostrar eficaz durante a fase de construção de um domínio de aplicação ou nos projetos de design de sistemas.

A proposta deste trabalho é demonstrar o reuso e as oportunidades para o melhoramento do design de sistemas através dos padrões de projeto. Será feita uma análise sobre os padrões encontrados, além da oportunidade de utilização de outros para a melhoria do software. Para demonstrar o uso dos padrões de projeto, será analisada uma aplicação que foi construída a partir dos padrões Java EE (Malks et al, 2003). O trabalho está dividido em 4 partes. A proposta e problemas relacionados na seção 1. Uma visão geral sobre os padrões de projeto na seção 2. As tecnologias utilizadas para a construção do software na seção 3. As conclusões na seção 4 e as referências na parte final deste artigo.

2. Padrões de Projeto

Durante a última década, o uso da modelagem de projeto, durante o desenvolvimento de software, tornou-se muito popular. Os padrões de projeto definem em sua essência, o reuso de boas idéias bem conhecidas, para resolver um problema particular. As idéias para os padrões de projeto originam-se do arquiteto Christopher Alexander, a partir dos seus livros:

The Timeless Way of Building” (Alexander, 1979) e “A Pattern Language” (Alexander, 1977). Os livros fornecem idéias e padrões para criar estruturas arquitetônicas da alta

qualidade. Os conceitos foram desenvolvidos, originalmente, com edifícios e os mesmos princípios foram utilizados no desenvolvimento de arquiteturas e de produtos de software. Erich Gama, Richard Helm, Ralph Johnson e John Vlissides, ou como são popularmente conhecidos: “The Gang of four” ou GoF, popularizaram o uso dos padrões no projeto de software com seu livro “Elements of Reusable Software” em 1995 (Gamma et al, 1995).

Os padrões de projeto usados no paradigma de orientação a objetos, estão em um nível acima da linguagem de programação, segundo (Metsker, 2004). Além de fornecer arcabouços conceituais, para a utilização de uma linguagem de representação como a UML (Unified Modeling Language) (Rumbaugh et al, 1999). Alguns livros versam sobre os tipos de padrões mais utilizados na engenharia de software atual, entre eles: “Analysis Patterns:

Reusable objects Models” (Fowler, 1997) – padrões para modelagem de softwares orientados a objetos – “Core J2EE Patterns: Best Practices and Desing Strategies” (Malks et al, 2003) – padrões de arquitetura para a plataforma Java Enterprise Edition (Sun, 2007) – e “Applying UML and Patterns, Second Edition” (Larman, 2002) – padrões de projeto para o design de sistemas.

Apesar de (Malks el tal, 2003) demonstrar o uso dos padrões de arquitetura J2EE, o livro utiliza os padrões do Gof (Gamma et al, 1995) como referência. Um exemplo de um padrão de projeto pode ser visto na Figura 1.

exemplo de um padrão de projeto pode ser visto na Figura 1. Figura 1 – Exemplo

Figura 1 – Exemplo do padrão de projeto Proxy (Silva, 2007 P. 7).

Para um programa cliente, usando a arquitetura cliente & servidor, tenha acesso a um software servidor construído com o RMI (Remote Method Invocation) (Sun, 2007), é preciso existir um objeto que represente a implementação da interface InterfaceEditorRemoto para invocar os seus métodos através de um representante ou proxy (Metsker, 2004, P. 115).

Tabela 1 – Exemplo de utilização do padrão Proxy (Silva, 2007 P. 18).

NameComponent component = new NameComponent( "ObjetoServidor", "" ); NameComponent path [] = {component}; interfaces.InterfaceEditorRemoto servImpl = InterfaceEditorRemotoHelper.narrow(ncRef.resolve(path));

servImpl.setLimpar(currX, currY, prevX, prevY);

Após a implementação da interface o cliente precisa invocar os métodos usando o

representante da classe, neste caso, o objeto servImpl, mostrado na Tabela 1. Este irá obter

a referência remota da instância da classe que implementa a interface

InterfaceEditorRemoto mostrada na Figura 1, possibilitando a invocação dos métodos em

um outro computador através do programa cliente. Este padrão também é utilizado no

Design Pattens Facade (Malks et al, 2003), na versão atual do EJB, conforme mostrado na seção anterior, para utilizar um bean de entidade é necessário usar um outro de sessão do tipo Stateless, servindo esse, como um representante para que as demais classes possam persistir dados sem acessar diretamente o bean de entidade. Na construção dos métodos é possível utilizar-se de outro padrão, o Data Transfer Objects (Malks et al, 2003), para que seja passado um objeto como parâmetro de entrada nos métodos de acesso ao bean de

entidade. Dessa forma, facilita a manutenção posterior, caso haja a inserção de novos atributos ou mudanças nas regras de implementação do bean de entidade.

Outro padrão utilizado para facilitar a programação de sistemas distribuídos é o Adaptive Comunication Environment (ACE) (Schmidt, 1993). O ACE fornece um toolkit contendo uma série de invólucros, categorias de classes e frameworks que ajudam na programação de serviços que operam sob uma rede de computadores em diversos tipos de sistemas operacionais. Entre as facilidades encontradas, é possível citar: o estabelecimento de conexões de serviços, demultiplexação e dispatch de eventos, IPC e protocolos de rede, gerenciamento e cachê de armazenamento primário e secundário, configuração estática e dinâmica de componentes e controle de concorrência e sincronização e threads. A Figura 2 mostra as categorias de classes do ambiente.

. A Figura 2 mostra as categorias de classes do ambiente. Figura 2 - Categoria de

Figura 2 - Categoria de classes do ACE (Schmidt, 1993, P.3).

Interfaces de programas para o usuário final são susceptíveis a trocas constantes. Em outros tempos, quando normalmente eram estendidas funcionalidades de uma aplicação desktop, habilitavam-se um ou mais menus, além de modificar o código-fonte. Muitas modificações não eram compatíveis com todos os gostos e cenários de utilização e o resultado era definir interfaces personalizadas, duplicando os componentes de acesso a dados e as regras de controle para sua exibição. Com o tempo, as tecnologias emergiram, e as empresas tiveram ao seu alcance outros equipamentos, entre eles, os portáteis (e.g. palms, celulares e notebooks). Em virtude da competitividade do mercado, as informações tinham de ser visualizadas mais rapidamente, em qualquer dispositivo com capacidade para tal e em qualquer lugar, pois a necessidade de criar novas soluções para um público diversificado com o mínimo de modificações foi crescente.

Ainda se gastava muito tempo para desenvolver as camadas de acesso á dados, de regras de negócio da aplicação e a interface para visualizar os dados e controlar as ações feitas pelos usuários, pois todos esses interesses eram misturados em um único componente, diminuindo a oportunidade de reuso de cada parte isoladamente. Existiam também outros problemas com relação á visualização da mesma informação em diferentes componentes, como: a necessidade da aplicação refletir imediatamente as atualizações dos dados na tela e o suporte a diferentes “look and feel” (Buschman et al, 1996) e que motivaram a criação do padrão arquitetural MVC. O padrão MVC divide a aplicação em três partes: o processamento, a saída e a entrada de dados através do modelo, controle e visualização dos dados respectivamente.

modelo, controle e visualização dos dados respectivamente. Figura 3 – Modelo de classes do padrão MVC,

Figura 3 – Modelo de classes do padrão MVC, (Buschman et al, 1996, P.129).

Conforme a Figura 3, o modelo ou model representa uma camada de acesso aos dados com ações de consulta, alteração, exclusão e inserção de registros e é construído independente da maneira em que os dados serão visualizados ou das regras de negócio do software. A visualização ou view representada as telas de interação com os usuários. Cada tela tem um controlador ou controller que antes de acessar o modelo verifica as regras,

encaminha os dados para outra janela, enfim, gerencia todas as ações e a maneira como os dados serão apresentados. O componente observer ou observador é opcional, pode ser utilizado para detectar as mudanças no modelo e notificar ao controlador para atualizar os dados na tela do componente view.

3. Desenvolvimento do trabalho

Para demonstrar o reuso dos padrões de projeto, foi construído um software que visa ajudar

o músico a manter informações sobre obras musicais na Internet, possibilitando a consulta

em qualquer lugar utilizando diversas mídias (e. g. palms, celulares e computadores pessoais) e o compartilhamento dessas informações com outros profissionais. Um programa

foi construído, utilizando as tecnologias EJB (Enterprise Java Beans) (Sun, 2008) versão 3

e Web services (Couloris et al, 2005) para manter um cadastro de obras musicais. As

informações, armazenadas em um banco de dados, focam o resumo de uma música, contendo os seus principais elementos: nome da música, tom, dominante primário e secundário, o tipo do acorde diminuto se ascendente, descendente ou alternativo e a existência de clichê harmônico. Estas informações podem ser comparadas a um abstract de um artigo científico e são úteis ao músico em um momento prévio á sua apresentação ou em seus estudos.

O desenvolvimento da aplicação utiliza as boas práticas dos padrões de projeto, com isso, a aplicação foi dividida em camadas de forma a facilitar a implementação e

manutenção das classes. O contêiner EJB utilizado foi o JBoss AS 4.0.5GA (JBoss, 2008),

o serviço Web foi implementado usando o JBoss-WS 1.0.3GA (Jboss WS, 2008), a versão

utilizada da Java Virtual Machine foi a 1.5.0 update 9, por questões de compatibilidade com as API’s utilizadas no contêiner EJB 3 (Jboss Forum, 2008).

3.2 Arquitetura da aplicação

A construção da aplicação foi divida em duas partes: a construção dos serviços no lado do servidor usando a tecnologia EJB e Web services e a utilização desses serviços pelos clientes.

EJB e Web services e a utilização desses serviços pelos clientes. Figura 4 – Diagrama de

Figura 4 – Diagrama de seqüência da arquitetura.

A Figura 4 apresenta a arquitetura de acesso á um serviço Web através de um

diagrama de seqüência (Rumbaught et al, 1999). Trechos de código para explanação de todas as classes serão mostrados na tabelas seguintes. Uma instância da classe WebserviceClient, através do código contido na Tabela 2, acessa a um serviço Web publicado no servidor de aplicação JBoss. A arquitetura foi dividida em camadas lógicas de forma a representar um certo isolamento de responsabilidades, diminuindo o acoplamento entres as classes. Na construção do programa foram utilizadas as camadas de persistência, lógica de negócios, delegação, serviço e apresentação.

de negócios, delegação, serviço e apresentação. Figura 5 – Planejamento da arquitetura do software. A

Figura 5 – Planejamento da arquitetura do software.

A Figura 5 demonstra como será a implementação do software através da exibição

por camadas. Cada retângulo representa uma camada e terá responsabilidades de acordo com o padrão representado do lado direito, para proporcionar uma arquitetura flexível a mudanças e de fácil entendimento. Ao longo deste capítulo serão detalhados os problemas, benefícios e modelos de classes sugeridos para implementação do software por camada de responsabilidade.

3.2

Construção do EJB

3.2.1

Camada de persistência

Na Tabela 2, é mostrado um trecho do código utilizado para a construção da camada de persistência aos dados usando um bean de entidade e o recurso de anotações do EJB 3. Para criar uma classe que representa uma tabela em um banco de dados foi utilizada a anotação @Entity antes do nome da classe, o método getID() irá gerar um novo identificador para uma nova música inserida no banco de dados. Para isto foi utilizada a anotação @GeneratedValue antes do nome do método. Foi criado também um método construtor padrão, conforme a especificação da JSR 109 (JCP, 2008), sem parâmetros de entrada e qualquer implementação.

Tabela 2 – Parte do código Java utilizado para construção do bean de entidade.

@Entity public class Musica implements Serializable {

public Musica(){} @Id @GeneratedValue public Integer getID() { return ID;

Na construção da camada de persistência, foi criado o arquivo persistence.xml, esse arquivo define várias informações para configuração das classes de persistência. Entre as configurações possíveis mostrada na Tabela 3, a informação da classe que representa uma tabela no banco de dados (e. g. beans.Musica), construída usando um bean de entidade é definida na linha 4. A configuração da fonte para o acesso ao banco de dados foi criada na linha 3 e o banco de dados utilizado é o HSQLDB (HSQLDB, 2008).

Tabela 3 – Arquivo de configuração da camada de persistência.

<persistence> <persistence-unit name="ManterMusicaFacade"> <jta-data-source>java:/DefaultDS</jta-data-source> <class>beans.Musica</class> <properties><property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="create-drop"/> </properties> </persistence-unit> </persistence>

A camada de persistência representa o modelo de dados, conforme mencionado no capítulo anterior, na arquitetura MVC. A Figura 6 mostra como será a forma de representação dos dados usando o componente model desta arquitetura em conjunto com a camada de lógica de negócios.

em conjunto com a camada de lógica de negócios. Figura 6 – Representação do modelo de

Figura 6 – Representação do modelo de dados e o seu acesso.

Qualquer cliente interessado em persistir ou recuperar os dados deverá utilizar a camada de acesso à lógica de negócios. Entre os problemas encontrados na abordagem tradicional de acesso ao modelo de banco de dados direto, é possível citar: a replicação de código para estabelecer a conexão, as mudanças nos métodos das classes que acessam o banco de dados devem ser replicadas na camada de visualização ou quando esta camada não mistura interesses de acesso, persistência e visualização de dados. Preocupações com requisitos não-funcionais (e.g. transações, logs, seções ou espaços de usuários). Entre os maiores benefícios encontrados quando do uso correto dos padrões MVC (Buschman et al, 1996) e Session Facade (Malks et al, 2003), estão o desacoplamento e coesão, através da divisão dos interesses entre as classes, o que ocasiona maior facilidade de manutenção. Além disso, os requisitos não-funcionais mencionados serão tratados pelo middleware. O modelo de dados utilizado no design pode ser um exemplo de reuso do padrão Memento (Gamma et al, 1995), pois facilita a persistência de dados a partir de instâncias de objetos.

3.2.2 Camada de lógica de negócio

A camada de lógica de negócio representa a visão do cliente, pode ser explicitada usando os diagramas de caso de uso da UML (Rumbaught et al, 2002), onde cada caso de uso representa uma ação a ser realizada pelo cliente na utilização do sistema. No projeto, foram definidas as ações de adicionar música, apagar música, atualizar as informações de uma música e a possibilidade do músico poder obter informações de uma ou vários músicas. Todas essas ações foram definidas utilizando uma interface remota, pois o sistema permitirá a sua utilização em máquinas virtuais Java em diferentes locais, conforme o código exibido nas Tabela 4. O padrão de projeto utilizado para definir o acesso a camada de persistência foi o Session Facade (Malks et al, 2003).

Tabela 4 – Definição e implementação da interface remota.

@Remote public interface ManterMusica { public void adicionarMusica(MusicaTO musicaTO); public void deletarMusica(MusicaTO musicaTO);

public void atualizarMusica(MusicaTO musicaTO); public MusicaTO selecionarMusica(MusicaTO musicaTO); public List selecionarMusicas();

}

@Stateless public class ManterMusicaFacade implements ManterMusica { @PersistenceContext(unitName="ManterMusicaFacade") private EntityManager entityManager; public void adicionarMusica(MusicaTO musicaTO) { entityManager.persist(new Musica(musicaTO));

}

De acordo com a Figura 6, o padrão Session Facade é utilizado para servir como uma fachada entre o bean de entidade, representado pelo componente model, e o componente de visualização da arquitetura MVC (Buschman et al, 1996), que será mostrado posteriormente. Este padrão reutiliza em sua forma de implementação o padrão de projeto Facade (Gamma et al, 1996). A proposta de sua utilização é ocultar os detalhes de implementação da camada de acesso aos dados, facilitando para o cliente o acesso aos dados das tabelas através de uma interface.

3.2.3

Camada de delegação

A camada de delegação fornece o acesso aos métodos de negócio para o cliente da aplicação, sem expor a camada de persistência e lógica de negócio. Na Tabela 5 é mostrado um trecho do código que implementa o padrão de projeto Delegate (Malks et al, 2003). Na construção da aplicação cliente, o programador precisa ter acesso apenas ás camadas de delegação e localização de serviço. Assim, as alterações na camada de negócio serão isoladas, diminuindo o acoplamento e facilitando a manutenção do sistema. O serviço de localização de instâncias remotas também é utilizado pela camada, proporcionando um ponto único e evitando a duplicação de código para estabelecimento de conexões.

Tabela 5 –Implementação da camada de delegação dos métodos de negócio.

public class ManterMusicaDelegate { private ServiceLocator serviceLocator; private ManterMusica ManterMusica; public ManterMusicaDelegate() throws MusicaException{ serviceLocator = ServiceLocator.getInstance(); try { ManterMusica = (ManterMusica) serviceLocator.lookup( ManterMusicaFacade.class.getSimpleName()+"/remote"); } catch (NamingException e) { System.out.print(e.getMessage()); throw new MusicaException(e.getMessage());

}

}

public void adicionarMusica(MusicaTO musicaTO) throws MusicaException{

ManterMusica.adicionarMusica(musicaTO);

}

ManterMusica .adicionarMusica(musicaTO); } … Figura 7 – Acesso oferecido à camada de visualização

Figura 7 – Acesso oferecido à camada de visualização para estabelecer conexão e acesso aos dados.

A Figura 7 mostra o padrão Delegate sendo utilizado, este padrão é uma implementação do padrão Proxy (Gamma et al, 1996), explicado no capítulo anterior, pois

utiliza uma interface remota, a ManterMusica, como representante da classe ManterMusicaFacade para acessar o modelo de dados.

3.2.4 Camada de serviço

A camada de serviço utiliza o padrão Service Locator (Malks et al, 2003) para localizar as

instâncias de objetos remotos, que representam a lógica de negócio através de suas

interfaces. A implementação do serviço de localização é mostrada na Tabela 6.

Tabela 6 – Serviço de localização de interfaces remotas.

public class ServiceLocator { private InitialContext ic; private static ServiceLocator me; public ServiceLocator() { try { ic = new InitialContext(); } catch (NamingException ne) { throw new RuntimeException(ne);

}} return ic.lookup(jndiName);

}

public static ServiceLocator getInstance() throws RuntimeException { if (me == null) { me = new ServiceLocator();

} return me;

}

public Object lookup(String jndiName) throws NamingException {

public Object lookup(String jndiName) throws NamingException { return ic.lookup(jndiName);

}

}

O serviço de localização cria um único ponto para buscas de objetos remotos e por não conter métodos que façam referência ás interfaces remotas com um tipo de retorno, como eram definidos nas versões anteriores ao EJB 3, ficou bastante fácil e reduzida a sua implementação. Além disso, faz o reuso do padrão Singleton (Gamma et al, 1996) para criar de um pool de conexões para o banco de dados e o seu gerenciamento em uma única instância.

3.2.5 Camada de apresentação

O acesso aos métodos de negócio é realizado pela aplicação cliente na camada de

apresentação dos dados utilizando a camada de delegação, como pode ser visto na Tabela 7.

A aplicação cliente, através do padrão Transfer Objects (Malks et al, 2003) irá utilizar um

objeto para passagem de referência. Essa abordagem foi utilizada para ocultar do cliente preocupações com definições de tipos de parâmetros utilizados nos métodos de negócio. Por questões de segurança, também foi ocultada a definição da classe que representa a camada de persistência criando uma réplica da classe (e. g. MusicaTO) sem as anotações.

Para acessar o serviço Web, o cliente da aplicação precisa acessar o arquivo WSDL

contendo a descrição do serviço. O contêiner EJB 3 gera o arquivo automaticamente, após a identificação das anotações contidas na Tabela 9. Com as informações do EndPoint, nome

do serviço Web e a URL do arquivo WSDL, é possível criar uma instância do serviço e

obter uma referência ao proxy da interface remota, assim utilizando o seus métodos de maneira estática para recuperar os dados, conforme visto na Tabela 7.

Tabela 7 – Código Java para acesso ao delegate em uma aplicação.

//Acesso ao delegate usado em uma aplicação cliente swing ManterMusicaDelegate delegate = new ManterMusicaDelegate(); List<MusicaTO> MusicaTo = new ArrayList<MusicaTO>(); MusicaTo = (delegate.selecionarMusicas());

//Acesso ao Web Service realizado por uma aplicação Java String nameSpace="http://business/jaws"; String service="SelecionarMusicasService"; String wsdl="http://localhost:8080/easd2007/SelecionarMusicasWS?wsdl"; URL url = new URL(wsdl); QName qname = new QName(nameSpace,service); ServiceFactory factory = ServiceFactory.newInstance(); Service remote = factory.createService(url, qname); SelecionarMusicas proxy = (SelecionarMusicas) remote.getPort(SelecionarMusicas.class); String[] musicas = proxy.selecionarMusicas();

A camada de apresentação foi construída pensando na arquitetura MVC (Buschman et al, 1996) e os benefícios obtidos com os padrões da arquitetura JEE (Malks et al, 2003). Conforme a Figura 8, um componente GUI (Graphical User Interface) que será a interface gráfica que o usuário irá ter acesso aos dados, será o componente que irá utilizar um componente view para fazer as requisições ao componente controller, representado pelo delegate. Com isso, o delegate, que já implementa as regras de negócio, não precisa ser alterado, nem a forma como se dá o acesso ao modelo de dados representado pelo bean de entidade Musica.

modelo de dados representado pelo bean de entidade Musica. Figura 8 – Camada de apresentação. A

Figura 8 – Camada de apresentação.

A implementação da classe Principal que interage com o componente view TelaManterMusica, habilita a criação de vários tipos de visualização para os dados, inclusive alterações da forma de composição de botões, caixas de texto e outros componentes visuais, pois podem ser utilizados diferentes layouts. Entre os benefícios alcançados com a distribuição dos componentes desta forma, é possível citar: a reutilização

do modelo de dados através do controller, facilitando as alterações em cada componente e isolando esses pontos aumentando a coesão. A reutilização da camada de lógica de negócios para construção dos métodos que devem ser apenas delegados pelo Web service através do padrão Wrapper Facade, explicado posteriormente, e a facilidade de requisitar e receber os dados com a utilização do padrão Transfer Object (Malks et al, 2003) entre todos os componentes evitando problemas com conversões de tipos.

3.2 Construção do serviço Web

É possível utilizar um contêiner EJB ou Web para publicar o serviço. Quando utilizado em um contêiner EJB, os métodos do serviço WEB podem ser implementados usando o bean de sessão do tipo Stateless. O arquivo WSDL será gerado automaticamente neste caso, contendo as informações sobre como acessar o serviço (e. g. um contêiner residente em um servidor de aplicação, um dispositivo móvel ou um aplicativo) no formato reconhecido por múltiplos protocolos como o SOAP 1.1 e 1.2 e XML. O componente Port é associado a um Endpoint contido no arquivo WSDL através de uma classe Java que provê a lógica de negócio e esta é ligada ao comportamento do contêiner. No contêiner existe um escutador de eventos para o Endpoint do arquivo WSDL e meios para despachar a requisição ao bean do serviço. Para acessar o serviço, o cliente deve utilizar o proxy, e assim, ter a referência do Web service localmente para executar os métodos.

Usando as anotações do EJB 3, conforme código-fonte mostrado na Tabela 8, é muito simples construir um serviço Web usando o EJB3. O serviço Web construído utiliza a API JAX-WS 2.0 (Raj, 2006). Com o uso dos padrões de projeto delegate, service locator e facade foi possível reutilizar os mesmos métodos da camada de negócios, delegação e localização de serviço na publicação do serviço Web. Caso esteja em outra máquina virtual, basta compilar e gerar as classes necessárias, sendo possível ainda, definir um arquivo externo com os nomes das interfaces remotas para que não haja a necessidade de modificação nas classes compiladas.

Tabela 8 – Código Java utilizado na criação do serviço Web.

@WebService @SOAPBinding(style = Style.RPC) public interface SelecionarMusicas extends Remote{ public String[] selecionarMusicas() ;

}

@Stateless @WebService(endpointInterface="business.SelecionarMusicas") @Remote(SelecionarMusicas.class) public class SelecionarMusicasWS { public String[] selecionarMusicas() throws MusicaException{ List<MusicaTO> musicas = new ArrayList<MusicaTO>(); ManterMusicaDelegate delegate; delegate = new ManterMusicaDelegate();

musicas = delegate.selecionarMusicas(); String[] musicasNomes = new String[musicas.size()]; int i=0; for (Iterator<MusicaTO> iter = musicas.iterator();

iter.hasNext();){ musicasNomes[i] = new String(iter.next().getNome()); i++;

}

return musicasNomes;

}

Entretanto, detalhes do estabelecimento da conexão com o servidor para invocar o serviço Web e de como foi implementada a camada de lógica de negócio, devem ser ocultados do lado do cliente, inclusive, para contemplar os requisitos de portabilidade e facilitar a manutenção do componente view que será provida ao usuário. Para a solução destes problemas, foram utilizados, em conjunto com os padrões JEE, os padrões do ACE Acceptor, Connector, Service Handler e Wrapper Facade. O Wrapper Facade encapsula as funções de baixo nível e estruturas de dados usando interfaces, facilitando a portabilidade, a robustez e a manutenção porque oculta os detalhes da implementação (Schmidt, 1999). Já os padrões Acceptor e Connector desacopla o estabelecimento da conexão e inicialização de serviços em sistemas distribuídos (Schmidt, 1997). A Figura 9 mostra como foram utilizados os padrões do ACE e a reutilização dos patterns JEE para prover a solução.

a reutilização dos patterns JEE para prover a solução. Figura 9 – Construção do serviço Web

Figura 9 – Construção do serviço Web e o seu modo de acesso feito pelo cliente.

O cliente do serviço Web irá utilizar-se da classe ManterMusicaDelegate para criar uma instância do serviço que deseja utilizar, para isso faz o uso da interface que encapsula os detalhes de implementação e torna a utilização do métodos remotos mais fácil pelo desenvolvedor. A conexão é feita através da classe ServiceLocator que, além de proporcionar um único ponto para a criação do End Point, estabelece a comunicação entre o modelo de dados, através do Session Facade e o cliente do serviço Web.

4.

Conclusão

Durante a última década, o uso da modelagem de projeto, durante o desenvolvimento de software, tornou-se muito popular. Os padrões de projeto definem em sua essência, o reuso de boas idéias bem conhecidas, para resolver um problema particular. Este trabalho apresentou a construção de uma aplicação distribuída utilizando as tecnologias EJB 3.0, padrões de projeto e a API JAX-WS 2.0 que facilita a construção dos web services usando as anotações. Foi utilizado o Enterprise Java Beans que é um framework voltado para a criação de componentes de software e a realização de uma série de serviços, como os web services.

Além de mostrar as facilidades encontradas atualmente nas tecnologias Java, o trabalho possibilitou a prática e demonstração do reuso dos padrões de projeto. Para isso, reutilizou os padrões JEE em conjunto com o Adaptive Comunication Environment (ACE) que fornece um toolkit contendo uma série de invólucros, categorias de classes e frameworks que ajudam na programação de serviços que operam sob uma rede de computadores em diversos tipos de sistemas operacionais e o MVC (Model View Controller), que divide a aplicação em três partes: o processamento, a saída e a entrada de dados através do modelo, controle e visualização dos dados respectivamente. Também foram mostrados alguns padrões Gof (Gamma et al 1995), que servem de base para a criação dos padrões da arquitetura JEE (Malks et al, 2003), proporcionando mais um exemplo de reuso.

5. Referências

Alexander C. (1979) “The Timeless Way of Building”, Oxford University Press, ISBN

0195024028.

Alexander C. (1977) “A Pattern Language”, Oxford University Press, ISBN

0195019199.

Alur, D., Crupi, J., Malks, D. (2003) "Core J2EE Patterns Best Pratices and Design strategies". Pearson, ISBN 0131422464.

Booch, G., Jacobson, I., Rumbaugh, J (1999). “Unified Modeling Language – User’s Guide”. Addison-Wesley, ISBN 0201571684.

(1996) “Pattern-

Buschmann, F., Meunier, R., Rohnert, H., Sommerland, P., Stal, M Oriented Software Architecture Volume 1: A System of Patterns”.

(2005) "Distributed Systems concepts and

Couloris, G., Dollimore, J., Kindberg, T

Design". Addison Wesley, 4º Edição, ISBN 0321263545.

Fowler, M. (1996) "Analysis Patterns: Reusable Object Models". Addison Wesley. ISBN 9780201895421.

Gamma E., Helm R., Johnson R., Vlissides J. (1995) “Design Patterns”, Addison-Wesley, ISBN 0201633612.

HSQLDB. (2008) “HSQLDB Database”, http://hsqldb.org/, Fevereiro.

JBoss.

4.0.5GA”,

(2008)

“JBoss

Application

Server

http://labs.jboss.com/jbossas/downloads, Fevereiro.

JBossWS.

(2008)

“JBoss

Web

Service

1.0.3GA”,

http://labs.jboss.com/jbossws/downloads, Fevereiro.

 

JBossForum.

(2008)

“JBoss

We

Service

Forum”,

http://www.jboss.org/?module=bb&op=viewtopic&t=103699, Fevereiro.

JCP. (2008) “Java Community Process”, http://jcp.org/en/jsr/overview, Fevereiro.

Larman, C. (2002) "Applying UML and Patters: An introduction to Object-oriented analysis and design and the Unified Process". Prentice Hall, ISBN 0130925691.

Metsker, S. J. (2004) "Padrões de Projeto em Java". Bookman, ISBN 8536304111.

Mukhar, k., Zelenak, C. (2006) "Beginni Java EE 5 from novice to Professional". Apress, ISBN 1590594703.

Raj, G. S., Binod P.G., Babo, K., Palkovic, R. (2006) "Implementing Service-Oriented Architecture (SOA) with the Java EE 5 SDK". Sun Microsystems, revision 3.

Schmidt, D. C. (1993) “The Adaptative Comunication Environment An Object-Oriented Network Programming Toolkit for Developing Comunication Software”. http://www.cs.wustl.edu/~schmidt/ACE-papers.html

Schmidt, D. C. (1999) “Wrapper Façade: A Structural Pattern for Encapsulating Functions Within Classes”. C++ Report Magazine, Fevereiro.

Schmidt, D. C. (1997) “Acceptor-Connector: An Object Creational Pattern for Connecting and Initializing Communication Services”. http://www.cs.wustl.edu/~schmidt/ACE- papers.html

Silva, J. B. (2007) “Paintbrush Distribuído usando RMI-IIOP e CORBA”. Especialização Avançada em Sistemas Distribuídos, trabalho parte da avaliação da disciplina de objetos distribuídos, Universidade Federal da Bahia.

Sun. Sun Microsystems (2008). “Java Technology”. http://www.java.sun.com. Fevereiro.