Você está na página 1de 16

IntegrandoDesignPatternsemArquiteturasde

Software

SérgioTeixeiradeCarvalho OrlandoGomesLoquesFi lho


sergiotc@ic.uff.br loques@ic.uff.br

ComputaçãoAplicadaeAutomação
InstitutodeComputação
UniversidadeFederalFluminense

Resumo

Acomposiçãodesistemaspartedadefinição deumaArquiteturade Software


que descreva seus componentes e o inter-relacionamento entre eles. O processo de
definiçãodaarquiteturaéchamadoConfiguração.

Design Patterns podem ser empregados quando da configuração de sistemas.


Designpatterns sãomeiosderepresentareregistrarassoluçõesdeprojetoe aexperiência
doprojetistaaodesenvolverestassoluções.

Nesterelatórioapresentamosumestudodecomoalguns designpatterns podem


ser empregados em conjunto com a configuração quando da elaboração e constru ção de
sistemasdistribuídos.Destacamos designpatterns consideradosdeinteraçãoentreobjetose
apresentamosexemplosdeimplementaçãoutilizandoconectoresR-RIO.
IntegrandoDesignPatternsemArquiteturasde
Software

SérgioTeixeiradeCarvalho OrlandoGomesLoquesF ilho


sergiotc@ic.uff.br loques@ic.uff.br

ComputaçãoAplicadaeAutomação
InstitutodeComputação
UniversidadeFederalFluminense

1-Introdução A composição de uma aplicação parte do


estabelecimentodoscomponentesenvolvidos
Aconcepçãodesoftwareconstitui-seuma e das suas interações. A definição de um
tarefa árdua em vários aspectos, sistema em termos dos componentes e das
particularmentenotocanteàreutilização. interações entre estes componentes é
chamada Arquitetura de um Sistema de
A reutilização de software é um aspecto Software [13]. A descrição de uma
há muito tempo discutido. A dificuldade em arquitetura é feita através de uma ADL
se consegui-la vem de décadas. A tentativa, (ArchitectureDescriptionLanguage ).
namaioriadoscasos,partiadareutilizaçãoda
fase de implementação, ou seja, apenas do O projetista, ao utilizar uma ADL,
código fonte da aplicação através de rotinas seleciona e especifica os componentes do
armazenadas em bibliotecas. Esta forma de sistema e os conectores. Este processo é
reutilização de software é plausível mas chamado Programação da Configuração, ou
insuficiente. simplesmente,Configuração.

O desenvolvimento de sistemas por Os conectores têm um papel fundamental


composição e a separação de interesses na configuração: são responsáveis por
constituem-se em conceitos primordiais para estabeleceraligaçãoentreoscomponentese
se alcançar a reutilização de software [4]. intermediar a interação entre os mesmos.
Construir sistemas por composição facilita a Além disso podem encapsular aspectos não
reutilização pois permite que componentes diretamenterelacionadosàfuncionalidadede
sejam adicionados ou removidos de forma determinada aplicação, enquanto os
transparente. Quanto à separação de componentes realizam preferencialmente os
interesses [2], esta distingue aspectos aspectosfuncionaisdamesmaaplicação.
funcionais de aspectos operacionais (não
funcionais) da aplicação. Como exemplo de Ainda com respeito à reutilização de
aspectos operacionais podemos citar softwareexistea preocupação emrelação ao
protocolos de comunicação entre reaproveitamento da “experiência” do
componentes em um sistema distribuído, projetista. Durante o projeto de software,
aspectosdetolerânciaafalhas,etc. objetosdevemser encontradosefatoradosem
classes, interfaces devem ser definidas,

2 de 16
hierarquias de herança precisam ser utilizar uma ADL para descrever os
estabelecidas,etc.Oconhecimentoacercado componenteseoselementosdeinterconexão
projeto, associado aos seus problemas e entreosmesmos,chamadosconectores.
soluções, pode ser reaproveitado para
utilização emoutros projetos vindouros, seja O desenvolvimento de software baseado
domesmoprojetistaouatémesmodeoutros. emconfiguraçãodeslocaofocodoprojetista
paraaarquiteturadosistema,constituídados
A idéia é documentar de forma componentes e suas interligações. A
padronizada problemas recorrentes visualização da arquitetura permite que
envolvendo classes e objetos em sistemas componentes sejam adicionados ou
orientados a objeto. Design patterns são removidos sem a preocupação com os
meios de representar e registrar as soluções detalhesdeimplementaçãodecadaumdeles.
de projeto e a experiência do projetista ao
desenvolver estas soluções [1]. Catálogos de A configuração tem como base a
design patterns podem ser criados e interligação de componentes através dos
consultadospordesenvolvedoresembuscada conectores. Os conectores estabelecem a
resolução de determinados problemas. Com interação entre os componentes e podem
isso, design patterns constituem-se em uma realizar qualquer atividade inerente à
forma padronizada de descrever problemas comunicaçãoentreestes.
reais, acompanhados de suas respectivas
soluções. 2.1–R-RIO( Reflective,Reconfigurable
InterconnectableObjects )
Neste relatório apresentamos um estudo
de como alguns design patterns podem ser A abordagem R-RIO ( Reflective,
empregadosemconjuntocomaconfiguração ReconfigurableInterconnectableObjects )[3,
quando da elaboração e construção de 4] permite que se descreva a estrutura de
sistemas.Paraissodestacamosalguns design aplicaçõesapartirdeseuscomponentes,suas
patterns [1] considerados de interação entre interligaçõeseseusaspectosnãodiretamente
objetos. Além disso apresentamos exemplos relacionados à sua funcionalidade, tais como
de como estes podem ser implementados a distribuição, coordenação, protocolos de
utilizando conectores R-RIO ( Reflective, comunicaçãoeoutros.
ReconfigurableInterconnectableObjects )[4]
atravésdalinguagemJava[5]. OmodelodeR-RIOestábaseadoemtrês
elementosbásicos[3,4]:
Este relatório está dividido em 6 seções.
Na seção 2 tratamos do processo de - Módulos: componentes de uma
configuraçãodesistemas edaabordagemR- aplicação que encapsulam sua
RIO para concepção de aplicações funcionalidade;
distribuídas. Os design patterns são - Conectores: elementos de conexão
caracterizados na seção 3. A seção 4 que implementam e gerenciam as
apresenta exemplos de implementação de interaçõesentreosmódulos;
alguns designpatterns deinteraçãoutilizando - Portas: pontos de acesso pelos quais
conectoresR-RIO.Conclusõesestãonaseção módulos e conectores oferecem ou
5easeção6listaasreferências. solicitamserviços.

2–ConfiguraçãodeSistemas A figura 1 mostra o inter-relacionamento


entreoselementosbásicosdeR-RIO.
A arquitetura de um sistema de software
define um sistema em termos dos Asclassesdemódulossãomapeadaspara
componentes e das interações entre estes umaimplementação.Porexemplo,Módulo1
componentes [13]. Configurar um sistema é e Módulo 2 são instâncias de módulos

3 de 16
implementados em Java, C ou C++. Cada os módulos podem ser instanciados em
módulo pode oferecer ou solicitar serviços qualquer hostdosistema.
por meio de portas de entrada e portas de
saída respectivamente. Ao implementarmos 2.2–Exemplo
por exemplo um módulo como uma classe
Java, teríamos como portas de entrada a Como exemplo apresentamos um sistema
declaraçãodosmétodosdaclasse.Quantoàs cliente-servidor simples. O módulo Cliente
portas de saída, estas seriam invocações de possui uma porta de saída e o módulo
método. Servidor possui uma porta de entrada. A
arquiteturadestesistemaésimilaràfigura1,
porta na qual o Módulo 1 pode representar o
Cliente e o Módulo 2 pode representar o
Módulo1 Módulo2 Servidor.

Conector
A figura 2 apresenta a descrição da
arquitetura utilizando a ADL do R-RIO
Figura1. Módulo 1 interage com Módulo 2 através de
chamada Babel ( Building Applications by
Conector. Evolution). A Babel permite a descrição, o
armazenamentoearecuperaçãodadescrição
Os conectores, ao interligarem módulos, de módulos, conectores e aplicações [4].
facilitam a separação de interesses, FundamentosdeBabelsãotratadosem[14].
permitindo a codificação de aspectos não
relacionados diretamente à funcionalidade Após a descrição da arquitetura faz-se
dosmódulosenvolvidos.Istoocorredevidoà necessário codificar os módulos
facilidade do mesmo em interceptar e correspondentes, instanciá-los e executá-los
manipular requisições de e para os módulos. nosistemaR-RIO.
Observamos com isso a capacidade de
reflexãodoconectorR-RIO. Os dois módulos foram implementados
como classes Java. O módulo Cliente
A reflexão, quando empregada, trata o simplesmente invoca um método do módulo
sistema em dois níveis: nível base e meta- Servidor.AportadesaídadomóduloCliente
nível. O primeiro é associado às (figura 3) é indicada pela invocação do
funcionalidades do sistema e o segundo é método obtemMsg()dainstância srv.
associado aos aspectos não diretamente
A porta de entrada do módulo Servidor
relacionados às funções do mesmo sistema.
(figura 4) é representada pela declaração do
Operaçõesrealizadasnonívelbasepodemser
método obtemMsg().
interceptadas e direcionadas para o meta-
nível. Este realiza o devido tratamento às Importantenotarqueasclassesdasfiguras
operações e as reencaminha, podendo 3 e 4 herdam características da classe Thread
inclusivedesviá-lasdeseucursonormal. do Java. Isto ocorre pois os módulos são
executados em R-RIO como threads.
A integração da configuração e reflexão Detalhespodemserencontradosem[3].
temsidoobjetodeestudo[4].
Após a codificação das classes é o
O sistema R-RIO [3] permite instanciar momento de instanciá-las no sistema. Além
módulos em um sistema, seja distribuído ou deinstanciá-lasem hostsdistintos,asligamos
não distribuído, ligar módulos através de através de um conector CORBA [6], já
conectores, parar módulos em execução, codificadoepertencenteaorepositóriodeR-
reiniciarestesmesmosmódulos,dentreoutras RIO. Os comandos necessários para as
funções.Paraocasodesistemasdistribuídos, instanciaçõesealigaçãoaoconectorestãona
figura5.

4 de 16
Protótipo do Sistema R-RIO – Versão 1.0
Entre com o comando no prompt
module AplicacaoExemplo { > instantiate Cliente as clnt at host1
module ClienteType { Ok.
outport obtemMsgType obtemMsg; > instantiate Servidor as serv at host2
map CODE Java “Cliente”; Ok.
} clnt; > link clnt at host1 serv at host2 with conectores.Corba
Ok.
> start srv at host2
module ServidorType { Ok.
inport obtemMsgType obtemMsg; > start clnt at host1
map CODE Java “Servidor”; Ok.
} serv;

conector CorbaC { Figura5. Comandos de Configuração.


inport obtemMsgType;
outport obtemMsgType;
map CODE Java “Corba”; Na próxima seção abordaremos conceitos
} corba; ecaracterísticasdos designpatterns afimde,
instantiate clnt at host1;
na parte 4, apresentarmos alguns deles
instantiate serv at host2; implementadosutilizandoconectoresR-RIO.
link clnt to serv by cCorbaC;
} Exemplo;
start Exemplo;
3– DesignPatterns

Figura2. Arquitetura da Aplicação Durante o projeto de software, objetos


devem ser definidos e fatorados em classes,
interfaces devem ser criadas, hierarquias de
herançaprecisamserestabelecidas,etc.
public class Cliente extends Thread {
Os projetistas, entretanto, podem
public Servidor srv;
reaproveitar projetos já aplicados e que
public void run () { tenham tido funcionalidade comprovada.
System.out.println (srv.obtemMsg()) ;
Projetistas experientes reutilizam soluções
}
}
quando estas são consideradas boas. Tais
soluçõessetornamentãopadrõesrecorrentes
de classes e objetos em muitos sistemas
Figura3. Código do Módulo Cliente. orientados a objeto [1]. Tais padrões
resolvemproblemasdeprojetosespecíficose
os tornam mais flexíveis, elegantes e
public class Servidor extends Thread { reutilizáveis.
public void run (){
} Os design patterns são mecanismos de
public String obtemMsg () {
return “Mensagem do Servidor”;
representação de problemas recorrentes
} acompanhados de suas respectivas soluções
} [1]. Eles permitem o compartilhamento da
experiênciadeespecialistasdediversasáreas
Figura4. Código do Módulo Servidor. econstituem-seemumamaneiradereutilizar
aexperiêncianoprojetodesoftware.
Os módulos Cliente e Servidor se
comunicam sem que tenham conhecimento Design patterns apresentam-se como
do mecanismo de comunicação empregado. descrições de soluções que tenham tido
Tal mecanismo é responsabilidade do sucesso em problemas de software [7]. A
conector. Mudar o estilo de comunicação idéia central é a possibilidade de se criar
entreoClienteeoServidoréfácil,bastando handbooks que descrevam problemas
para isso utilizar o conector apropriado, conhecidosesuassoluções.
digamos SocketsaoinvésdeCORBA.

5 de 16
Importantesalientarentretantoque design informação à qual ele representa e deve ser
patterns não são construções teóricas, mas tratado como um poderoso mecanismo que
sim artefatos descobertos em múltiplos tragaàtonaoseusignificado.
sistemas [8]. Uma solução representada em
um designpattern deve ter sido aplicada,no Problema:esteéoproblemaespecíficoa
mínimo,três vezes [16].Emoutras palavras, ser resolvido. Descreve o objetivo do design
não é feito o registro apenas de uma boa pattern,quandoaplicá-loeocontextoaoqual
idéia, mas sim de uma solução aplicada em aplicá-lo, ou seja, a configuração na qual o
umcenárioreal. problemaéencontrado.

Outracaracterísticaimportantedos design Solução: descrição da essência da


patterns é a sua independência de qualquer solução,istoé,componentesenvolvidos,seus
linguagem de programação. As soluções relacionamentos e responsabilidades. A
estão ligadas a aspectos inerentes à solução solução é dada em notação UML ( Unified
em si. Portanto, eles podem ser aplicados a Modeling Language ) [17], descrição dos
qualquer domínio e em qualquer linguagem participantes e diagramas de interação. Em
deprogramação[8]. alguns patterns, esta seção traz cartões CRC
(Class-Responsibility-Collaborator) ou CRC
Design patterns têm sido empregados no cards [18]. É importante salientar que este
contextode frameworksorientadosaobjetos. elemento do design pattern não descreve a
Um framework orientado a objeto é um implementação, mas sim as técnicas que
conjunto de classes que cooperam poderiam ser empregadas para implementá-
mutuamente umas com as outras [9], lo.Umexemplodeimplementaçãotambémé
compondo a infra-estrutura necessária ao apresentado.
desenvolvimento de uma aplicação
específica. Ao construir um framework, o Conseqüências: este elemento descreve
projetista deve definir classes e seus as conseqüências após a aplicação do design
relacionamentos, de tal forma que possa pattern. Aqui são descritos os impactos para
atender aos requisitos de determinada o usuário decorrentes da sua aplicação,
aplicação. Design patterns podem ser através da especificação de vantagens e
empregados na fase de projeto de um desvantagens, além da relação custo-
framework.Exemplospodemserencontrados benefício. Também são apresentados design
em [10] e [11]. Mais detalhes de como um patternsrelacionadosàqueleemquestão.
framework é construído podem ser
encontradosem[12]. Napróximaseção,apresentaremos alguns
designpatterns relacionadosàinteraçãoentre
3.1–Descriçãodeum DesignPattern objetos. Abordaremos a aplicação destes à
configuração de sistemas distribuídos
Um design pattern identifica as classes e utilizandoconectoresR-RIO.
instâncias participantes, seus papéis e
colaborações, e a distribuição de 4–Configuraçãoe DesignPatterns
responsabilidades [1]. Sua descrição é feita
atravésde4(quatro)elementosessenciais[1, Oníveldereutilizaçãoqueaconfiguração
8]. e os design patterns alcançam é diferente.
Utilizando uma ADL para descrever os
Nome: palavra ou frase que descreve o componentes e conectores, o projetista
designpattern .Devesintetizaroconceitoque consegue configurar aplicações com
representa, minimizando os problemas de características de reutilização. Isso ocorre
comunicação.Onomedeum designpattern , pois os componentes envolvidos são
assim como o nome de um algoritmo ou de independenteseinteragemunscomosoutros
uma estrutura de dados, deve deixar clara a através de conectores, responsáveis pela

6 de 16
interligação. Quanto aos design patterns , (behavioral patterns ). Design patterns de
estes possibilitam a reutilização de software criação estão associados ao processo de
relacionadaà expertiseempregada.Emoutras criaçãodeobjetos;deestruturatratamcoma
palavras, podemos reaproveitar o que outros composição de classes ou objetos e os de
projetistas já desenvolveram em termos de comportamento caracterizam as formas nas
modelo e projeto. Esse reaproveitamento quais os objetos ou classes interagem e
podesedarporintermédiodoscatálogos[1], distribuemresponsabilidade.
dos sistemas [19], ou das linguagens de
patterns[20] . Nocontextodesterelatório,alguns design
patterns são interessantes para aplicação em
O emprego de design patterns na conectores, principalmente aqueles
configuração facilita a separação de relacionadosàinteraçãoentreobjetos.Dentre
interesses. Aspectos não relacionados estesdestacamos4(quatro):
diretamente à funcionalidade da aplicação
podem ser implementados preferencialmente - Chain of Responsibility (de
nos conectores e os aspectos funcionais comportamento);
podem ser codificados nos módulos da - Visitor(decomportamento);
aplicação. O projeto de um conector nem - Memento(decomportamento);
sempre é um processo trivial pois envolve a - Proxy(deestrutura).
definiçãodeclasses,hierarquias einterfaces.
Este projeto poderia então ser reaproveitado A partir das próximas subseções
através dos design patterns já existentes, apresentaremos uma descrição de cada um
elevandoareutilizaçãodesoftwarecomoum destes e um exemplo de implementação dos
todo. mesmosutilizandoconectores.Umacitaçãoa
outros design patterns de interação que
Nesta seção apresentamos como alguns poderiam ser implementados utilizando
design patterns podem ser implementados conectoreséfeitanofinaldestaseção.
utilizando conectores na construção de
sistemas de software. O critério adotado na Todos os exemplos de implementação
escolha dos design patterns é o fato de foram criados no ambiente R-RIO [4]
participarem como elementos de interação utilizando a linguagem Java. Detalhes a
entre objetos. Chamaremos tais design respeito de cada um dos design patterns
patternsde designpatternsdeinteração ,que citadosestãoem[1].
uma vez implementados utilizando
conectores, permitem a interligação dos 4.1.1– ChainofResponsibility
módulosenvolvidosnaconfiguração.
Sempre que um objeto (emissor) invoca
4.1–Implementaçãode Design Patternsno um método de outro objeto (receptor), o
R-RIO últimorespondelogoemseguida,criandoum
acoplamento entre o emissor e o receptor. O
Um dos mais conhecidos catálogos é o objetivo deste design pattern é diminuir este
livro Design Patterns: Elements of Reusable acoplamento, permitindo que outros objetos
Object-Oriented Software [1]. Os autores possamtratardopedidosolicitado.
levantaram design patterns de uso geral sem
se aterem a nenhuma aplicação de domínio Para que isto seja possível, objetos
específico. “candidatos” a tratar o pedido formam uma
cadeia de objetos receptores. Desta forma o
No livro [1], os design patterns pedido é retransmitido até que algum objeto
apresentadosestãoorganizadosemtrêstipos: dacadeiapossatratá-lo.
de criação ( creational patterns) , de estrutura
(structural patterns ) e de comportamento

7 de 16
Um ponto interessante neste design Podemos tratar a cadeia do exemplo
pattern é sua capacidade de isolar o emissor dentrodeumconectoreusá-loparainterligar
das possíveis manipulações que podem oclienteeoservidor.Oconectorimplementa
ocorrer na cadeia. O cliente (emissor) nada aspectos não diretamente ligados à
sabe sobre o comportamento dos objetos na funcionalidadedaaplicaçãosemqueocliente
cadeia,seestesatenderãoaopedidoounão. ou o servidor tomemqualquer conhecimento
disto.
Outroaspectoimportanteéapossibilidade
de estabelecermos o conjunto de objetos O conector chamado de ChainOfResp
componentesdacadeiademaneiradinâmica. possuiduasportas:umainterligadaàportade
O sistema poderia ter objetos anexados à saídadomóduloClienteeoutrainterligadaà
cadeiaouremovidosemtempodeexecução. porta de entrada do módulo Servidor (figura
7).
Como exemplo imaginemos a seguinte porta

situação: um cliente precisa invocar um


método de um objeto por ele instanciado Cliente
Servidor
(servidor) e, durante a invocação, outros
objetos interceptarão o pedido, farão um ChainOfResp
tratamentoaopedidoecuidarãodeconclui-lo
Figura7. Design Pattern Chain of Responsibilit y
juntoaoservidor.Afigura6retrataocenário. implementado no conector.

Aspectosrelevantes: Aconfiguraçãoutilizando esteconector é


- Cliente invoca método do servidor análoga à apresentada na figura 2, trocando-
assincronamente,ouseja,nãoaguarda se o conector CORBA pelo conector
retornodomesmo. ChainOfResp.
- Qualquerdosobjetos quecompõema
cadeia pode concluir o pedido do O design pattern em questão, quando
cliente ao servidor (na figura 6, o implementado utilizando conector, ratifica a
último objeto da cadeia conclui o capacidade de reflexão dos conectores R-
pedido). RIO. A cadeia de objetos realiza atividades
- Se determinado objeto da cadeia não não relacionadas diretamente à
pode concluir o pedido ao servidor, funcionalidade do sistema. Esta é então
encaminha o pedido para o próximo implementada no meta-nível utilizando-se o
dacadeia. conector. Os módulos Cliente e Servidor,
- Um objeto invoca um método do nestecontexto,fariampartedonívelbase.
próximo objeto da cadeia
assincronamente. AspectosdeImplementação
- Tantoocliente,o servidor, quanto os
objetos encadeados podem estar em O conector ChainOfResp é composto
máquinas distintas em um ambiente principalmente de 3 classes: StartChain,
distribuído. Handlere FinishChain.Ainstânciadaclasse
StartChain solicita ao primeiro objeto da
cadeiaquetrateainvocaçãofeitapeloCliente
(figura3).Apartirdaí,cadaobjetodacadeia
invoca seu sucessor até que um deles possa
executar a invocação solicitada pelo Cliente.
Cliente Servidor Quandodeterminadoobjetodacadeiaprecisa
executar a invocação solicitada pelo Cliente,
Figura6. Exemplo do design pattern Chain of invoca assincronamente o construtor de
Responsibility. FinishChain. Este encaminha finalmente o

8 de 16
pedido ao Servidor, também de forma em máquinas distintas. Quando da
assíncrona. configuração de módulos em máquinas
distintas, este conector suporta comunicação
A classe abstrata Handler é responsável via Sockets, CORBA ou RMI. Em nossos
por implementar a cadeia de testes implementamos o conector
responsabilidade. Cada objeto pertencente à ChainOfRespcomcomunicaçãovia Sockets.
cadeiaéumainstânciadeumaclasseherdada
de Handler(figura8). 4.1.2– Visitor

Emdeterminadossistemasexistemclasses
sucessor
Handler cujos métodos podem ser agregados com o
objetivodeserealizarumaúnicaoperação.O
forward ( ) design pattern Visitor possibilita a
handleRequest( )
representação desta operação, e ainda que a
mesmasejarealizadaemmaisdeumobjeto.

Como exemplo simples, imaginemos 2


Classe1 Classen (duas) classes representativas de 2 (dois)
handleRequest( )
... handleRequest( )
componentes de um microcomputador. As
classes são HD (disco rígido) e Vídeo
(monitor de vídeo). Estas classes possuem
Figura8. Classe Abstrata Handler. Classe 1, Classe 2 ... diversos métodos, dentre eles métodos com
Classe n representam as classes que serão
instanciadas como parte da cadeia. responsabilidadedecalcularopreçodevenda
do componente. Diante deste cenário é
possível que seja necessário obter o preço
A figura 9 apresenta o código da classe consolidado dos 2 (dois) componentes. Para
abstrata Handler. isso métodos específicos para o cálculo de
preço têm que ser executados em cada
Sempre que determinado objeto que instância das respectivas classes. Em outras
compõe a cadeia quer repassar a palavras, precisamos “visitar” cada instância
responsabilidade a seu sucessor, invoca o e executar o(s) método(s) correspondente(s)
método forward(). Como as classes aocálculodopreçoeobterototal.
envolvidas na cadeia sobrepõem o método
handleRequest(), oobjetoinstanciadoapartir O designpatternVisitor tratadesituações
desta classe pode executar suas atividades e, como esta. Uma estrutura para percorrer os
seconveniente,executar ométodo forward() objetoséestabelecidaecadaobjetoévisitado
paradarseguimentoàcadeia. à procura de métodos que satisfaçam
determinado requerimento. No exemplo
acima, este requerimento traduz-se no preço
import rrio.suporte.*; { dosequipamentos.
abstract class Handler {
Handler sucessor = null;
public void handlerRequest( ) { A classe abstrata Visitor (figura 10)
} mantémuma interfacecommétodos capazes
public void forward( ) {
if (this.sucessor != null) de agregar invocações aos métodos das
classes envolvidas e que atendam ao
this.sucessor.handleRequest( ); requerimento. Por exemplo, os métodos
}
} visitVídeo e visitHD, implementados na
Figura9. Código da classe abstrata Handler.
classe VisitorPreço, invocam métodos da
classe Vídeo e da classe HD que possam
O conector ChainOfResp interliga calcular o preço do monitor de vídeo e do
módulosemumamesmamáquinaemódulos disco rígido respectivamente. Cada classe

9 de 16
concreta oriunda da classe abstrata Visitor 11), o conector monta o código
representa um requerimento que deve ser correspondenteaométodo accept, associando
satisfeito. A classe VisitorPreço é um o Visitor desejado (VisitorPreço) ao objeto
exemploderequerimento. que precisa ser visitado. Desta forma o
conector pode encaminhar a requisição
Visitor diretamentepara ainstância do módulo (HD
visitVídeo (Vídeo) ou Vídeo), através da porta de entrada do
visitHD (HD) mesmo módulo. A totalização do preço de
cada equipamento é feita na classe
VisitorPreço,dentrodoconector.

VisitorPreço VisitorInventário
public class Cliente extends Thread {
visitVídeo (Vídeo) ... visitVídeo (Vídeo)
visitHD (HD) visitHD (HD) public HD h;
public Video vid;
VisitorPreco v;
Figura10. Classe Abstrata Visitor.
double precoHD;
double precoVideo;
As classes Vídeo e HD originais, para public void run ( ) {
seremutilizadascomo designpatternVisitor , precoHD = h.accept (v);
precoVideo = vid.accept (v);
precisam de apenas uma modificação: a }
adição do método accept(Visitor v) ao seu }
conjunto de métodos. A classe HD, por
exemplo,deveteroseguintecódigoparaseu Figura11. Código do Módulo Cliente.
método accept(Visitor v):
v.visitHD (this);
HD
visitHD por sua vez invoca os métodos da
classe HD correspondentes ao Visitor
Visitor
desejado (no exemplo VisitorPreço). Como Cliente
Cliente
veremos, a implementação do Visitor como
conector torna desnecessária esta declaração Vídeo

nosmódulosenvolvidos.
Figura12. Design Pattern Visitor implementado no
AspectosdeImplementação conector.

VamoschamardeCliente,oprogramaque
precisautilizaroVisitorPreçoparacalcularo Aspectos relevantesdaimplementação do
preço dos equipamentos. A figura 11 Visitornoconector:
apresentaseucódigo.
- Osmódulosnãotêmanecessidadede
Um conector correspondente ao design declarar o método accept dentre as
pattern Visitor pode ser construído demais operações. Isto ocorre pois o
interligando o módulo Cliente com os conector tem condições de descobrir,
módulos que se deseja visitar, conforme durante a execução, o Visitor
mostradonafigura12. requerido e o módulo envolvido,
através de reflexão. Desta forma os
A classe abstrata da figura 10 é módulos obtêm transparência em
implementadadentrodoconector.Aoreceber relação ao processo realizado pelo
a invocação do método h.accept(v) (figura Visitor.

10 de 16
- A adição de novas operações, que um instantâneo ( snapshot) do estado interno
dependemdosmétodosexistentesnos deoutroobjeto.
módulos é facilitada. Para isso basta
adicionar nova classe ao conector A figura 13 apresenta a estrutura do
Visitor. Por exemplo, a classe Memento.
VisitorInventário foi adicionada à
classeabstrataVisitordafigura10. Originator
- O Cliente apresentado na figura 11 é setMemento (Memento m) ο
simples e realiza a visita aos objetos createMemento ( ) ο
”h” e “vid”. Entretanto, é possível
state
estabelecer uma estrutura de objetos
mais complexa, como por exemplo
umalista. return new Memento (state)
- O conector nãoimpede que o Cliente Memento
invoque diretamente os métodos dos getState ( )
objetosqueparticipamdeum Visitor. setState ( )
Porexemplo,oClientepodeinvocaro state = m.getState( )
state
método que recupera características
técnicasdomonitordevídeo:
vid.caracTecnicas( ); Figura13. DesignPattern Memento. O objeto Originator
torna disponível seu estado para o
Assim como o conector ChainOfResp, o armazenamento em Memento.

conector Visitor podeserimplementado com


características distribuídas. Os módulos
O objeto Memento armazena o estado
Cliente, HD e Vídeo, por exemplo, podem
internodoobjeto Originatoresomentepode
estar em hosts diferentes, sendo a
seracessadoporestemesmoobjeto.
comunicação realizada pelo conector,
utilizando Sockets,RMIouCORBA.
Quandoqualqueroperaçãoquemodifique
oestadode Originatoréacionada,ométodo
4.1.3– Memento
createMemento( ) deve ser invocado para que o

Em um sistema pode ser necessário estado torne-se disponível. Por outro lado,
manter o estado interno de determinados quando da operação de undo (desfazer a
objetosparticipantes.Oestadodeumobjetoé última operação), o método
setMemento(Memento m) deve ser acionado para
útil,porexemplo,paraoperaçõesenvolvendo
checkpoints ou undo. Tais mecanismos são buscar o estado anterior armazenado em
requeridos quando se deseja desfazer uma Memento.
operação realizada ou recuperar-se de erros.
Para se desfazer uma operação é necessário AspectosdeImplementação
armazenaroestadodoobjetoenvolvidopara
que,posteriormente,arecuperaçãodomesmo O design pattern Memento pode ser
sejapossível. implementado através de conector como
mostraafigura14.
Entretanto objetos mantêm seus estados
Na implementação, o módulo Servidor
encapsulados, tornando-os inacessíveis a
outros objetos do sistema. A exposição dos possuiumainterfacecommétodosinerentesà
estados violaria o encapsulamento, ferindo a sua funcionalidade, mais os dois métodos
confiabilidadeeaextensibilidadedomodelo. responsáveisemtornardisponívelseuestado
( setMemento( ) e createMemento( ) ). Portanto o
O design pattern Memento resolve este móduloServidortemcorrespondênciacomo
problemamantendoumobjetoquearmazena objeto Originator mostrado na figura 13, ou

11 de 16
seja,precisamanterumestadocomobjetivos Cliente está invocando o método update(), o
derestauração. conector invoca createMemento() do módulo
Servidor,oqualcriaoMemento,salvandoo
Quanto ao Cliente, este apenas invoca estadodoServidor.Apósesteprocessamento
métodos do módulo Servidor, provocando ainvocaçãoaométodo update() éretomada.
mudanças no estado deste último. Além
disso, o Cliente pode, a qualquer instante,
solicitar a operação de undo para desfazer a public class Servidor extends Thread {
últimaoperaçãoefetuadanoServidor.
int state = 0;

Memento createMemento() {
Cliente
Cliente Servidor
Servidor Memento m = new Memento (state);
return m;
Memento
}

Figura14. Design Pattern Memento implementado no void setMemento (Memento m) {


conector. state = m.getState();
}

boolean update(int arg) {


O conector, graças à sua capacidade de // ... código para atualizar o estadostate...
reflexão,podeinterceptarasinvocaçõesfeitas }
pelo Cliente ao Servidor. As interceptações boolean undo() {
permitem ao conector gerenciar e controlar // ... apenas o código funcional relacionado
// ... à operação undo(). A execução do
vários mementos criados pelo módulo // ... undo() não precisa ser feita aqui.
Servidor, além de tornar transparente a este // ... Ela é executada no conector.
mesmo módulo o momento da criação e }
}
acessoaosmementos.Istotornaocódigodo
móduloServidormaissimplesededicadoaos
seusaspectosfuncionais. Figura15. Código do Módulo Servidor.

O módulo Clientetambémtemvantagens
com relação à implementação deste design O Cliente, quando necessário, pode
patternatravésdoconector.O designpattern desfazer a última operação invocando o
Memento apresentado em [1] assume que o método undo(). Esteérealizadonoconector,o
objeto Caretaker (correspondente ao nosso qualinvocaométodo setMemento() doServidor
móduloCliente) deveinvocar explicitamente para restauração do estado. Se alguma
os métodos createMemento( ) e setMemento( ) para funcionalidade precisa ser executada após a
permitir ao Originator salvar seu estado e operação undo(), esta pode ser codificada no
recuperá-lo, respectivamente. A nossa módulo Servidor (figura 15). Outro ponto
implementação não exige esta invocaçãopor interessante desta solução é a possibilidade
parte do Cliente. O Cliente precisa apenas do conector gerenciar e controlar vários
invocar os métodos inerentes à instantâneos( snapshots)domóduloServidor.
funcionalidade da aplicação e o conector Uma possibilidade seria, por exemplo,
invocará,nomomentoadequado,osmétodos empilhar os instantâneos. O cliente poderia
citadosacima. assim desfazer, por exemplo, 5 (cinco)
operaçõesrealizadas.
Comoexemploapresentamosnafigura15
uma possível interface para o módulo Este conector, como os demais, pode
Servidor. separar os módulos Cliente e Servidor em
hosts distintos utilizando Sockets, RMI ou
Quando o módulo Cliente invoca o CORBA.
método update() de Servidor, o conector
intercepta a invocação. Ao descobrir que o

12 de 16
4.1.4– Proxy comcapacidadedecodificação(criptografia).
O conector ligaria o Cliente, localizado em
Os 3 (três) design patterns até agora um host, ao Servidor, localizado em outro
apresentados ( Chain Of Responsibility , host. A invocação por parte do Cliente seria
Visitor e Memento) são classificados por [1] interceptada e codificada para o envio até o
em design patterns de comportamento. O móduloServidor.
Proxy, último ao qual apresentaremos um
exemplo,éoúnicoclassificadocomo design
pattern deestrutura. Subject
request( )
...
O Proxyofereceumaespéciedesubstituto
paraoutroobjetocomoobjetivodecontrolá-
lo. Proxyéaplicávelemsituaçõesnasquaisé
necessáriaumareferênciamaisversátil aum
RealSubject realSubject Proxy
objeto.Porexemplo, proxiesdeproteçãosão
request( ) request ( ) ο
úteis para verificar os direitos de acesso a ... ...
determinadoobjeto.Antesquealgummétodo
deste objeto seja invocado, o objeto proxy
verifica se o originário da mensagem tem
permissãodeacessoaoobjetodestino. ...
realSubject.request( )
...
A estrutura do design pattern Proxy
aparecenafigura16. Figura16. Design Pattern Proxy. O objeto Proxy tem a
mesma interface do objeto destino
RealSubject.
O objeto Proxy possui a mesma interface
doobjetodestino.Destaformaestetemuma
referênciaaoobjeto destinoe pode controlar
oacessoaomesmo.
Cliente
Cliente Servidor
Servidor
AspectosdeImplementação
Proxy

Como ilustração da potencialidade do Figura17. Design Pattern Proxy implementado no


conectornaimplementaçãodo design pattern conector.
Proxy, implementamos um conector que
verifica se um objeto Cliente possui 4.2–Outros DesignPatterns
permissão para invocar métodos do objeto
Servidor. A configuração do sistema é Design patternsqueenvolvemainteração
apresentadanafigura17. entre objetos são candidatos em potencial à
implementação utilizando R-RIO. Outros
A capacidade de reflexão do conector citados em [1] e que poderiam ser
simplifica de maneira considerável o implementados utilizando conectores R-RIO
problema proposto. O conector tem a são:
capacidadedeinterceptarasinvocaçõesfeitas - Observer
pelo Cliente e realizar qualquer verificação - Mediator
necessária. Os módulos Cliente e Servidor - State
não têm conhecimento da presença do - Iterator.
mecanismo de verificação de permissão
implementadonoconector Proxy. Todoselestêmcaracterísticasdeinteração
entre objetos. O Observer define uma
Outro exemplo de Proxy seria a dependênciaum-para-muitosentreobjetostal
implementação de um conector distribuído quequandoumobjetomudaseuestado,todos

13 de 16
seus dependentes são notificados e RIOoqualligariaclientesdeListaaoobjeto
atualizadosautomaticamente.Umexemplode Lista e ainda estabeleceria a interface e
implementação do design pattern Observer mecanismosnecessáriosparapercorrê-la.
utilizando conectores R-RIO pode ser
encontrado em [15]. O exemplo é uma 5–Conclusão
aplicação do jogo TicTacToe (“jogo da
velha”)noqualumjogadorexecutaoslances A concepção de sistemas de software
e módulos Display recebem a atualização da passa pela arquitetura de software. Esta
situaçãodojogo.Estes módulosrepresentam representa os componentes definidos e a
osobservadoresdojogo. inter-relação entre eles. A definição de uma
arquiteturaéfeitaatravésdeumaADL.
O Mediator define um objeto que
encapsula como um conjunto de objetos A utilização de uma ADL possibilita a
interage, evitando que os objetos deste seleção e especificação dos componentes do
conjunto referenciem-se explicitamente. Este sistema e conectores. Em R-RIO os
design pattern age como um elemento conectores interligam módulos (nome dado
centralizador, “roteando” as mensagens de por R-RIO a componentes), facilitando a
umobjetoaoutro.Eleéaplicadoquandoum separação de interesses. Conectores R-RIO
conjunto de objetos se comunica de forma possuemcapacidadedereflexão,umavezque
bem estruturada entretanto complexa, têm facilidade em interceptar e manipular
tornando dificultada a reutilização de um requisiçõesdeeparaosmódulos.
objeto. O Mediator poderia ser construído
atravésdeumconectorR-RIOinterligandoos Neste relatório apresentamos a
objetosdoconjuntoporeleinterligado. implementação de design patterns no
ambiente R-RIO, particularmente utilizando-
Objetos mantêm estados internos e estes se conectores. Analisamos design patterns
podem se alterar conforme execução do relacionados à interação entre objetos e, a
sistema. O design pattern State permite que partir do catálogo [1], destacamos quatro
um objeto altere seu comportamento quando deles para implementação e testes no
da alteração de seu estado. Um conjunto de ambiente R-RIO: Chain of Responsibility ,
subclasses é estabelecido para tratar cada Visitor, Memento e Proxy. Implementamos
possível estado do objeto, particionando o estes quatro utilizando conectores R-RIO e
comportamento para os diferentes estados. citamos outros, também relacionados à
MaisumavezaestruturadeR-RIOfacilitaa interação, que podem ser implementados:
implementação.Nocasodo State,oconector Observer, Mediator, Statee Iterator.
ficaria encarregado de manter este conjunto
de subclasses, mantendo conseqüentemente Nossos estudos, implementações e testes
ospossíveisestadosdoobjeto. comprovamque designpatterns deinteração,
de forma geral, podem ser implementados
Finalmente, o Iterator também pode ser com a utilização de conectores R-RIO. O
tratadoporR-RIO.Muitasvezesdeterminado ambiente R-RIO, dadas suas características
objeto representa seqüências, nas quais os de distribuição e separação de interesses,
elementos devem ser acessados. Este design facilita a implementação de design patterns
pattern permite este acesso sem que a queenvolveminteraçãoentreobjetos.
representação do objeto precise ser exposta.
Umalistaporexemplopoderiaserpercorrida Além disso, conectores R-RIO tornam
utilizando múltiplos mecanismos, oferecidos possível o tratamento de aspectos não
pela classe do design pattern chamada relacionados diretamente à funcionalidade
ListIterator.Destaforma,ainterfaceoriginal dosobjetosenvolvidos. Visitor,porexemplo,
do objeto Lista seria preservada. Iterator envolveainteraçãoentreummóduloCliente
poderia ser encapsulado em um conector R- e um ou mais módulos que são “visitados”.

14 de 16
As instâncias destes módulos e do módulo [6] OMG, “The Common Object Request
Cliente interagem de forma transparente, Brocker: Architecture and
ignorando o conector. O conector, neste Specification”, Revision 2.3, Dezembro,
contexto, faz o papel de um Visitor atuando 1998.
narealizaçãodeaspectoscomplementaresda
aplicação,nãoprevistosouencapsuladosnos [7] Schmidt,D.,C.,Fayad,M.,Johnson,R.
seusmódulosbásicos,quandodeseuprojeto. “Software Patterns”, ACM
Communications,vol.39,n.10,outubro
Os design patterns de interação citados 1996.
foram implementados e testados utilizando
conectores R-RIO. A partir do estudo [8] Rising, L. “Patterns: A Way to Reuse
apresentado neste relatório, investigaremos a Expertise”.IEEECommunications,abril
possibilidade de se implementar design 1999.
patterns no R-RIO de tal forma que estes
possam se adequar às aplicações de forma [9] Budd, T. “On Introduction to Object-
transparente.Teríamosassimumaespéciede Oriented Programming” – Second
repositóriode designpatterns implementados Edition.Addison-Wesley,EUA,1996.
e prontos para se adequarem ao contexto de
umadeterminadaaplicação. [10] Srinivasam, S. “Design Patterns in
Object-Oriented Frameworks”. IEEE
6–Referências Computer,fevereiro1999.

[1] Gamma, E., Helm, R., Johson, R., [11] Suzuki, J., Yamamoto, Y.
Vlissides,J. “Design Patterns: Elements “OpenWebServer: An Adaptative Web
of Reusable Object-Oriented Software”, Server Using Software Patterns”, IEEE
Addison-Wesley,EUA,1995. Communications,abril1999.

[2] Sztajnberg, A. “Flexibilidade e [12] Adair, D. “Building Object-Oriented


SeparaçãodeInteresses paraConcepção Frameworks”. AIXpert, fevereiro e
e Evolução de Sistemas Distribuídos”. março1995.
Exame de Tese de Doutorado. COPPE-
UFRJ,março,1999. [13] Shaw M., DeLine, R., Klein, D., Ross,
T., Young, D., Zelesnik G.,
[3] Lobosco, M., “Um Ambiente para “Abstractions for Software Architecture
Suporte à Construção e Evolução de and Tools to Support Then”, IEEE
Sistemas Distribuídos”, dissertação de Transactions on Software Engineering,
mestrado,IC/UFF,março,1999. Vol.21,No.4,Abril1995,pp.314-335.

[4] Loques, O., Leite, J., Lobosco, M., [14] Malucelli, V.V., “Babel – Construindo
Sztajnberg, A., “Integrating Meta-Level Aplicações por Evolução”, dissertação
Programming and Configuration de mestrado, DEE / PUC-RJ, Fevereiro
Programming”, Workshop on Object 1996.
Oriented Reflection and Software
Engineering, OOPSLA’99, Denver, [15] Sztajnberg,A.,Lobosco,M.,Loques,O.
Colorado,novembro1999. “Configurando Protocolos de Interação
na Abordagem R-RIO”, SBES,
[5] Arnold, K., Gosling, J., “The Java Florianópolis,SantaCatarina,1999.
Programming Language”, Second
Edition, Sun Microsystems, Addison- [16] Appleton, B. “Patterns and
Wesley,EUA,1998. Software:Essential Concepts and
Terminology”, disponível em

15 de 16
http://www.enteract.com/~bradapp/docs/
patterns-intro.html,2000.

[17] Booch, G., Rumbaugh J., Jacobson I.,


“The Unified Modeling Language User
Guide”. Object Technology Series.
Addison-Wesley,1999.

[18] Ambler, S. W., “CRC Modeling:


Bridging the Communication Gap
Between Developers and Users.” White
PaperAmbysoft.Novembro,1998.
Disponívelem
http://www.ambysoft.com/crcModeling.
html.

[19] Buschmann, F., Meunier, R., Rohnert,


H.,Sommerlad,P.,Stal,M.,“A System
of Patterns-Pattern-Oriented Software
Architecture”.JohnWiley&Sons,1996.

[20] Schmidt, D., Stal, M., Rohnert, H.,


Buschmann F. “Pattern-Oriented
Software Architecture-Patterns for
Concurrent and Networked Objects”,
Volume2.JohnWiley&Sons,2000.

16 de 16

Você também pode gostar