7. Framework Baseado em Componentes
7.1. Considerações Iniciais
Este capítulo trata da construção de um framework baseado em componentes de software. Há uma seção específica sobre desenvolvimento de frameworks. Em outra seção está descrito o framework para mecanismos de anotações, o qual é uma das principais contribuições deste trabalho. O projeto do framework aliado às arquiteturas implementadas, às discussões e aos estudos realizados despertaram a seguinte hipótese:
H5: A tarefa de implementação de um framework de aplicação é também uma estratégia complementar de investigação do domínio de aplicação, pois a identificação de pontos fixos e adaptáveis permite estudos e descrições detalhadas de cenários por vezes imprecisos. Como o domínio de aplicação do framework é de cunho educacional, tais imprecisões na descrição dos cenários de uso são freqüentes, principalmente no que concerne os conceitos a serem implementados.
7.2. Desenvolvimento de Frameworks
7.2.1. Definição
Framework pode ser definido sob dois aspectos [Johnson 97]: estrutura e função. Quanto à estrutura, um framework é a reutilização do design de parte ou totalidade de um sistema representado por classes abstratas e pela forma como instâncias destas classes interagem.
Em outras palavras, a estrutura de um framework consiste de um diagrama de classes e um diagrama de eventos. Quanto à função, um framework é o esqueleto de uma aplicação que pode ser personalizado por um desenvolvedor de aplicação. Em outras palavras, a função do framework é extrair e disponibilizar a essência de uma determinada família de aplicações, de modo que o desenvolvedor possa partir de um patamar superior de implementação da arquitetura. Neste sentido um framework tem a mesma função que uma API (Application Programming Interface).
7.2.2. Classificação
Os frameworks podem ser classificados em caixa-branca e caixa-preta [Fayad 97]. Os frameworks caixa-branca baseiam-se nos mecanismos de herança e ligação dinâmica (dynamic binding) presentes em orientação a objetos. Os recursos existentes em um framework caixa-branca são reutilizados e estendidos a partir de: herança de classes do framework e sobrecarga (overriding) de métodos "hook" pré-definidos. Métodos "hook" são definidos em interfaces ou classes abstratas e devem necessariamente ser implementados por uma aplicação. Um exemplo de método hook na linguagem Java é o actionPerformed(Action Event e) pertencente à interface ActionListener do framework AWT (Abstract Window Toolkit). Este método é chamado sempre que ocorre um evento ActionEvent correspondendo, por exemplo, a um clique de botão. Os padrões de projeto (design patterns) utilizados são o Command, o Observer e o Template Method [Gamma 94].
Frameworks caixa-preta são baseados em componentes de software. A extensão da arquitetura é feita a partir de interfaces definidas para componentes. Os recursos existentes são reutilizados e estendidos por meio de: definição de um componente adequado a uma interface específica e integração de componentes em um framework que utiliza padrões de projeto como o Strategy [Gamma 94].
Quanto ao contexto de utilização do framework há uma classificação proposta em [Fayad 97], segundo a qual os frameworks são classificados em: "Framework de Infraestrutura de Sistema", "Framework de Integração de Middleware" e "Framework de Aplicação".
Frameworks de infraestrutura de sistema tratam de questões de projeto como sistemas operacionais, comunicação, interfaces gráficas e linguagens de programação. O framework AWT seria classificado como um framework de infraestrutura de sistema.
Frameworks de integração de middleware são responsáveis por integrar aplicações distribuídas e componentes em uma mesma arquitetura. Exemplos de frameworks de middleware são os ORB (Object Request Broker) como o CORBA - Common ORB Architecture, e o RMI - Remote Method Invocation.
Frameworks de aplicação tratam de questões de projeto de domínios de aplicação, como telecomunicações, finanças, produção e educação. O framework que se está desenvolvendo neste trabalho é um framework de aplicação.
7.2.3. Desenvolvimento baseado em Hot Spots ou Pontos Adaptáveis
Uma definição para framework do ponto-de-vista do desenvolvimento seria a seguinte [Codenie 97]: um framework é definido como uma arquitetura de software reutilizável em termos de contratos de colaboração entre classes abstratas e um conjunto de pontos adaptáveis, ou hot spots. Hot spots consistem de pontos adaptáveis que precisam ser especializados em uma aplicação. Os contratos de colaboração definem as regras que tal especialização deve obedecer. Um ponto adaptável é implementado a partir de padrões de projeto (design patterns) e tais padrões consistem na principal documentação de um framework [Gamma 94]. O projeto dos pontos adaptáveis é a tarefa central na construção de um framework.
O desenvolvimento que adotamos segue algumas recomendações expostas em [Albrecht 97], que consistem de uma sistematização para identificação e projeto de hot spots. O projeto de um hot spot passa pela implementação de um subsistema de hot spot. Um subsistema de hot spot é o nome dado a uma solução baseada em um ou mais padrões de projeto. O subsistema de hot spot substitui uma estrutura especializada de classes no framework e é também responsável por implementar a adaptabilidade desejada.
Um exemplo de padrão de projeto que permite a implementação de um subsistema de hot spot é o padrão Strategy [Gamma 94]. Este padrão permite isolar variações causadas por mudanças em determinado algoritmo. Um exemplo de uso deste padrão seria a necessidade de escolher entre vários algoritmos para compor o conteúdo de um documento com as respectivas anotações. A Figura 20 demonstra um uso deste padrão para escolher entre algoritmos de composição de documentos e anotações.
Figura 20 - Exemplo de uso do padrão Strategy
O processo de identificação e projeto dos hot spots é feito em ciclos, de modo que o framework está sempre sendo revisitado após alguma novidade gerada por uma aplicação. A sistematização proposta em [Albrecht 97] consiste de três passos:
- criar um diagrama de classes para a aplicação de acordo com o respectivo framework de aplicação;
- identificar os pontos adaptáveis dentro desta arquitetura, com isso tem-se o texto que chamado "requisito de variabilidade de hot spots";
- proceder uma atividade de generalização da estrutura de classes, de modo a incorporar as adaptabilidades especificadas anteriormente. Tal generalização é feita a partir da substituição da estrutura classes especializadas por um hot spot. O projeto do hot spot deve ser baseado em um ou mais padrões de projeto.
7.3. Metaphorai: Um Framework para Mecanismos de Anotações
O framework Metaphorai é um framework de aplicação. Por ser baseado em componentes é classificado como caixa-preta. Juntamente com a especificação das interfaces dos componentes, há dois frameworks caixa-branca: FactoriesObject e DocumentComposition, que são acompanhados de duas APIs. Estas APIs facilitam, por meio de mecanismo de herança e pela reutilização de classes, o desenvolvimento de componentes adequados às interfaces projetadas.
A convivência de frameworks caixa-preta e caixa-branca em um mesmo framework é um fato freqüente. Tal constatação é discutida em [Brugali 97] juntamente com a questão da evolução de um framework. Segundo Brugali et al [Brugali 97], a evolução de um framework implica na adição de novos componentes que fortalecem o caráter caixa-preta ao mesmo tempo que o caráter caixa-branca é reduzido. Tal fato decorre da detecção de outros graus de generalidade para os hotspots ou mesmo a descoberta de outros hotspots.
O framework caixa-preta corresponde às interfaces dos componentes da arquitetura básica de um mecanismo de anotações. A comunicação entre estas interfaces, de modo a obter um documento com anotações, está mostrada na Figura 21.
Figura 21 - Comunicações entre os Componentes do Framework.
A seguir temos a discussão sobre os dois frameworks caixa-branca: o FactoriesObject e o DocumentComposition.
FactoriesObject
A API correspondente a este framework está disponível em [Web - 8].
A abordagem de projetar fábricas para os objetos persistentes do mecanismo de anotação foi uma experimento para estudar a possibilidade de estendê-lo ao ambiente CALM, definindo assim um framework para composição de objetos complexos
Os pontos adaptáveis que norteiam o desenvolvimento do framework FactoriesObject correspondem à seguinte pergunta:
- Como poderemos acrescentar novos tipos de lugares-de-anotação, documentos e anotações?
Acrescentar novos tipos de documento, lugar-de-anotação e anotação implica na criação de uma fábrica para cada novo tipo criado. Portanto, além da adaptação a novos tipos é necessário poder adaptar novas fábricas à arquitetura.
As soluções de design que permitem esta adaptabilidade baseiam-se nos padrões de projeto AbstractFactory, FactoryMethod e Bridge [Gamma 94]. As famílias de classes correspondem as classes Document, Place e Annotation (Figura 21). As fábricas de cada família correspondem às interfaces AbstractFactory, DocumentsFactory, PlacesFactory, AnnotationsFactory (Figura 22).
![]()
Figura 22 - Famílias de Classes
Figura 23 - Fábricas
Além deste esquema de fábricas e famílias de classes foi disponibilizada uma interface para o componente que representa o serviço e fábricas de objetos, o FactoriesObject. A interface FactoriesObject define o contrato básico que deve ser cumprido por qualquer componente que implemente esta interface. Este contrato corresponde aos métodos públicos mostrados na Figura 23.
![]()
Figura 23 - Interface FactoriesObject.
De modo a auxiliar o desenvolvimento de um componente de acordo com a interface FactoriesObject, foram providenciadas as interfaces FactoriesComposition e ExternalCacheAdapter. Estas interfaces estão mostradas na Figura 24.
Figura 24 - Pontos Adaptáveis FactoriesComposition e ExternalCacheAdapter
A interface FactoriesComposition é responsável por organizar as fábricas de acordo com os tipos de objetos que estão sendo requisitados para composição. A classe que implementa esta interface deve manter uma lista das fábricas de todos os produtos, bem como providenciar, quando necessário, que as fábricas possam se comunicar para requisitar a produção de partes de um produto maior(por exemplo, lugares-de-anotação para um documento).
A interface ExternalCacheAdapter permite que a fábrica utilize um cache central em vez de seu próprio cache. Esta interface deve ser implementada por uma classe que se comunica com o componente (ex. FactoriesBean) de modo a enviar requisições a um possível serviço externo de cache. Há um serviço de cache baseado em componentes já implementado por um colega do projeto Sapiens. A intenção é que o serviço de fábricas seja integrado a este serviço.
As interfaces FactoriesComposition e ExternalCacheAdapter foram implementadas pelas classes FactoriesComposing e CacheAdapting (ver Figura 16).
DocumentComposition
Esta interface define o contrato estipulado para componentes responsáveis pela composição de documentos e respectivas anotações. A adaptabilidade pretendida com este framework é a possibilidade de compor outros tipos de documentos além do HTML. Na Figura 20 esta a solução de design que suporta tal adaptabilidade. Esta solução foi baseda nos padrões Strategy e Bridge [Gamma 94]. A interface DocumentComposition foi implementada pelo componente DocumentComposerBean (Figura 14).