Baixe o app para aproveitar ainda mais
Prévia do material em texto
Reengenharia de Software usando Transformações (RST) Valdirene Fontanette, Vinícius C. Garcia, Adriano A. Bossonaro, Angela B. Perez, Antonio F. Prado Universidade Federal de São Carlos - Departamento de Computação Rod. Washington Luiz, km 235 - São Carlos – São Paulo C.P. 676 - CEP 13565-905 Fone/Fax: 16-260-8232 {valdirene, vinicius, bossonaro, angela, prado}@dc.ufscar.br ABSTRACT This work presents a strategy for Software Reengineering using Transformations, which integrates a software transformation system, a CASE tool and other technologies to reconstruct legacy systems using distributed components. The strategy is accomplished in 4 steps: Organize Legacy Code, Recover Project, Reproject and Reimplement. In the Organize Legacy Code step, the legacy code is organized, using transformations, according to the principles of the Object Orientation, segmenting it in supposed classes, attributes and methods. The Recover Project step starts off with the organized legacy code and also using software transformations, generates its project description in the Modeling Domain Language, MDL. The MDL descriptions are read in a CASE tool, recovering the legacy code project, represented with UML techniques. In the Reproject step, the Software Engineer reprojects the system with distributed software components. New functional and non-functional requirements can be added in this step. The Catalysis method is used to reproject the distributed component-oriented system. Finally, in the Reimplement step, the system reimplementation is done in an executable language target of the reimplementation. The system final code can be generated in a CASE tool or using transformations. The CASE tool generates the code through the specifications of the new distributed component-oriented project and the transformational system through its MDL description. Keywords: Software Reengineering, Reverse Engineering, Object Orientation, Software Transformation, Distributed Components and Reuse. 1. INTRODUÇÃO Vários projetos na área de Reengenharia de Software têm como objetivo pesquisar técnicas modernas para automatizar grande parte das tarefas de manutenção de software, reduzindo seus custos. Atualmente, existe um grande número de empresas que continuam trabalhando com sistemas implementados em linguagens de programação antigas, cujas manutenções são árduas e onerosas. Sistema de software é um artefato evolutivo e requer constantes modificações, seja para corrigir erros, melhorar desempenho, adicionar novos requisitos ou mesmo para adaptá-lo para novas plataformas de hardware e software. Ao longo dos anos, esses sistemas incorporam conhecimentos substanciais do seu contexto, incluindo novos requisitos e regras de negócio. Esses conhecimentos tornam estes sistemas a principal fonte de recursos para sua evolução contínua. Na maioria dos casos, estes sistemas, denominados legados, ainda são de muita utilidade aos seus usuários e muitas vezes, suas reconstruções, usando técnicas modernas de desenvolvimento de software, poderiam ser a solução para suas reutilizações sem ter que construir um novo sistema. Normalmente, os sistemas legados não possuem documentação ou quando possuem, a mesma está desatualizada, e nem sempre a pessoa que desenvolveu o sistema é a responsável pela sua manutenção. Fatores como estes tornam difícil e de alto custo a manutenção, fazendo com que os desenvolvedores até abandonem o sistema. Esta dificuldade em atualizar sistemas legados para a utilização de tecnologias recentes, como distribuição e componentização, tem motivado os pesquisadores a investigar novas soluções para diminuir seu custo de desenvolvimento, garantir funcionalidade do sistema legado e um tempo de vida maior, e facilitar sua manutenção[1,2]. As técnicas recentes utilizam a Orientação a Objetos e a Computação Distribuída como base. A simples adoção da Orientação a Objetos, sem a existência de um padrão de reuso e de um processo de desenvolvimento de software orientado ao reuso, não fornece o sucesso esperado para a produção de software em grande escala[3]. A reengenharia de software é também uma forma de obter a reutilização de software e o entendimento do domínio da aplicação. As informações das etapas de análise e projeto são recuperadas e organizadas de forma coerente e reutilizável. Motivados por estas idéias pesquisou-se uma estratégia de reengenharia cujo objetivo é recuperar o projeto do sistema legado, reconstruindo-o principalmente para atender novos requisitos e ser executado em novas plataformas de hardware e software. A estratégia suporta reconstrução do sistema, inclusive com alteração da sua estrutura original, garantindo sua evolução contínua através da reutilização de componentes de software distribuídos. Um componente pode ser visto como um bloco de software, independente, contendo dados e operações, que pode ser utilizado na reconstrução de um sistema. Um dos atributos principais desejáveis em um componente de software relaciona-se a sua possibilidade de operaração em diversos padrões de plataforma computacional. Na estratégia, os componentes podem ser utilizados na reespecificação e reprojeto, e reimplementação do sistema segundo o método Catalysis. Esta alternativa permite ao Engenheiro de Software remodelar o sistema para ser executado numa arquitetura distribuída. Para melhor compreensão da estratégia proposta, segue uma apresentação das principais tecnologias integradas para suportar a Reengenharia de Software Orientada a Componentes Distribuídos usando Transformações. 2. SISTEMA DE TRANSFORMAÇÃO DRACO Diferentes sistemas de transformação têm sido usados em projetos de engenharia e reengenharia de software destacando-se o IllumaSM[4], Popart[5]. Outro importante sistema de transformação de software que vem sendo utilizado é o Draco[6,7,8,9]. Geralmente, um sistema de transformação reestrutura um programa A em um programa B, aplicando um conjunto de transformações bem definidas preservando as semânticas de A em B. O Sistema de Transformação (ST) Draco, foi construído com o objetivo de testar, desenvolver e colocar em prática o paradigma Draco. Trata-se de um sistema de transformação baseado na idéia de construção de software por transformação orientada a domínios. Com a estratégia proposta por Prado[10], é possível a reconstrução de um software pela “transformação” direta do código fonte em uma linguagem para linguagens de outros domínios. Um domínio, segundo o paradigma Draco, é constituído de três partes[7]: linguagem, prettyprinter e transformadores, conforme mostra a Figura 1. A linguagem do domínio é usada para descrever as especificações do domínio. Possui um parser que é gerado automaticamente pelo subsistema pargen do Draco a partir das definições da gramática da linguagem. O parser gera automaticamente a representação interna dos programas, escritos na linguagem domínio, que são manipulados pelo Draco. Esta representação interna das descrições na linguagem de um domínio, é denominada Draco Syntax Abstract Tree (DAST). O prettyprinter ou unparser: realiza a formatação da DAST, tornando-a novamente textual na linguagem do domínio. Baseado nas definições da gramática o subsistema ppgen do Draco gera o respectivo prettyprinter. Os transformadores mapeiam estruturas sintáticas de uma linguagem para outras estruturas sintáticas, que podem estar na mesma linguagem de domínio, chamados transformadores Intradomínio, ou em outra linguagem de domínio, chamados transformadores Interdomínios. Os transformadores são responsáveis pela automatização do processo de reconstrução de software. A Figura 1 mostra também a seqüência de execução das transformações. Inicialmente, parte-se do programa fonte A, que é analisado peloparser, o qual é responsável em gerar a DAST1. Aplicando as transformações Intra ou Interdominíos, tem-se uma nova DAST2. Usando o prettyprinter obtém-se um novo programa fonte B. São usados diferentes pontos de controle nas transformações. Normalmente tem-se o LHS (Left Hand Side) e o RHS (Right Hand Side), que definem os padrões de reconhecimento e substituição, respectivamente. O ST Draco dispõe ainda de uma Base de Conhecimento (Knowledge Base), que permite armazenar fatos e regras com informações sobre o código legado, que são consultadas durante as transformações. Outro recurso do Draco é o Workspace, usado para agrupar ou desagrupar comandos do código legado em blocos, durante a sua organização segundo os princípios da orientação a objetos. A Base de Conhecimento também facilita a execução de transformações, que necessitam de informações capturadas por outras transformações. Para facilitar o desenvolvimento dos domínios no ST Draco foi construída a ferramenta denominada Draco Domain Editor (DDE) que suporta a edição textual e gráfica das gramáticas, que dão origem aos parsers e unparsers dos domínios, dos transformadores Inter e Intradomínios e de scripts para execução dos transformadores. O DDE auxilia o Engenheiro de Software que utiliza o ST Draco disponibilizando, em um mesmo ambiente, recursos para a edição dos domínios e para aplicação das transformações. Sem o DDE, o Engenheiro de Software tem que editar o domínio em outro ambiente diferente do ST Draco. Para que se tenha uma idéia do DDE a Figura 2 mostra a tela para a edição da gramática de um domínio definido no ST Draco. Figura 1 – Domínio Draco Figura 2 – Draco Domain Editor (DDE) À esquerda (1) tem-se uma estrutura de diretórios onde estão localizados os domínios do ST Draco. Selecionando-se, por exemplo, o domínio Clipper pode-se visualizar sua gramática na forma textual (2) ou gráfica (3). Na tela (2) o Engenheiro de Software pode editar a gramática, obtendo-se a representação gráfica da sua árvore gramatical (3). O DDE possibilita ao Engenheiro de Software navegar na árvore gramatical e verificar cada nó correspondente às definições dos símbolos terminais e não-terminais da gramática. Diferentes cores sinalizam cada nó da árvore gramatical. O amarelo identifica um símbolo terminal (token), regra “RESIDENT”. O ícone SA denota um símbolo que tem ação semântica associada, “init_tela()”. O cinza denota um símbolo não terminal, cuja derivação leva a uma regra de expressão regular no analisador léxico, regra “IDVACOMP”. O branco identifica um símbolo não terminal sem problemas de derivação. O vermelho identifica um símbolo não terminal com problemas de derivação, regra “screen_cnt” por exemplo. O DDE também permite que o Engenheiro de Software automatize o processo de execução das transformações, escrevendo Scripts de Execução das Transformações. Usando esta meta-linguagem, o Engenheiro de Software define a seqüência de execução dos transformadores e de outras tarefas como criação de diretórios e cópias de arquivos. O primeiro passo do processo de execução das Transformações é identificar a seqüência dos arquivos que serão transformados. Para esta seqüência, definem- se os transformadores que serão aplicados. O script direciona todo o processo de execução das transformações. 3. FERRAMENTA MVCASE A MVCASE[11,12] é uma ferramenta CASE orientada a objetos que suporta a especificação de requisitos do sistema usando técnicas UML[13]. Permite a construção de modelos gráficos e textuais que representam o sistema em diferentes níveis de abstração. Os modelos gráficos de uma especificação na MVCASE facilitam a comunicação entre os desenvolvedores do sistema e seus usuários. Atualmente, a MVCASE dispõe das seguintes técnicas UML, organizadas em quatro visões: • Visão de Casos de Uso: Diagrama de Casos de Uso, Documentação do Caso de Uso e Diagrama de Seqüência; • Visão Lógica: Diagrama de Classes e Diagrama de Estados; • Visão de Componentes: Diagrama de Componentes; • Visão “Deployment”: Diagrama de “Deployment”. A MVCASE suporta também o Desenvolvimento Baseado em Componentes (DBC), utilizando a tecnologia Enterprise Java Beans (EJB)[14] para implementação. O Engenheiro de Software pode transformar o Modelo de Objetos de um sistema em Modelo de Componentes Distribuídos, que podem ser do tipo EJB Entity ou EJB Session. A MVCASE pode também gerar o código Java/EJB dos componentes. Além do código Java/EJB, a MVCASE gera as descrições em XML, que disponibilizam os componentes, em um servidor EJB, para serem reutilizados pelas diferentes aplicações. A ferramenta MVCASE foi desenvolvida visando suportar a estratégia, através da construção de um ambiente integrado à aplicação da estratégia. A escolha da MVCase se deve também pelo fato de ela ser uma ferramenta desenvolvida em java e portanto multi-plataforma, assim como o ST Draco que foi desenvolvido em C e é de livre distribuição. 4. MÉTODO DBC CATALYSIS Catalysis[15] é um método de desenvolvimento de software baseado em componentes que utiliza técnicas UML para modelar Sistemas com Componentes Distribuídos. O método Catalysis começou em 1991 como uma formalização do OMT e teve influências dos métodos Fusion[16] e UML[13]. Tem como base os princípios: Abstração, Precisão e Componentes Plug-In. O princípio Abstração orienta o Engenheiro de Software na busca dos aspectos essenciais do sistema, dispensando detalhes que não são relevantes para o contexto do sistema. O princípio Precisão objetiva descobrir erros e inconsistências na modelagem, e o princípio Componentes “Plug-In” visa a reutilização de componentes para construir outros componentes. Catalysis apresenta modelos precisos e um processo de desenvolvimento completo e sistemático, que cobre as diferentes fases do ciclo de vida do componente, desde a identificação e análise dos seus requisitos até seu projeto e implementação. O processo de desenvolvimento de software em Catalysis segue as características do modelo Espiral da Engenharia de Software[17], e é dividido em três níveis lógicos: Domínio do Problema, Especificação dos Componentes e Projeto Interno dos Componentes, correspondendo às atividades tradicionais do ciclo de vida do software: Identificação dos Requisitos, Especificação, Projeto e Implementação, que são executadas de forma incremental e evolutiva, resultando na geração de uma nova versão de um protótipo a cada ciclo realizado. No nível Domínio do Problema é dado ênfase na identificação dos requisitos do sistema, especificando “o que” o sistema deve fazer para solucionar o problema. Identificam-se os tipos de objetos e ações, agrupando-os em diferentes visões por áreas de negócio. No nível Especificação dos Componentes dá-se ênfase na identificação, comportamento e responsabilidades dos componentes. Neste nível faz-se o refinamento dos modelos de negócios, do domínio do problema. No nível do Projeto Interno dos Componentes dá-se ênfase no projeto físico dos componentes, preocupando-se com seus requisitos não-funcionais, e com suas distribuições físicas. Foram estudados vários métodos para Desenvolvimento Baseado em Componentes e optamos por Catalysis em razão da clara divisão entre as fases para o desenvolvimento dos componentes e dos princípios que ele se baseia. 6. REENGENHARIA DE SOFTWARE USANDO TRANSFORMAÇÕES (RST) Combinando as tecnologias do sistema de transformação Draco, da ferramenta MVCASE, de Engenharia Reversa e do método DBC Catalysis, com o ST Draco e a ferramenta MVCase, definiu- se uma estratégia para Reengenharia Orientada a Componentes Distribuídos, realizada em 4 passos: Organizar Código Legado, Recuperar Projeto, Reprojetar e Reimplementar, conforme mostra a Figura 3. 6.1. Organizar Código LegadoEste passo, Organizar Código Legado, é um passo preparatório para facilitar a transformação de um código procedural para Orientado a Objetos. O Engenheiro de Software com o auxílio do ST Draco e de técnicas de Engenharia Reversa, organiza o código legado, segundo os princípios da orientação a objetos. O código legado, escrito de forma procedural, possui comandos e declarações que podem ser organizados, sem prejuízo da sua lógica e semântica, de forma a facilitar sua transformação para o paradigma orientado a objetos, que tem a classe como a unidade básica. O Engenheiro de Software reúne toda a documentação disponível sobre o sistema legado, principalmente os seus programas fontes. Elabora a relação CHAMA/CHAMADO[16], para determinar a seqüência de programas a serem submetidos às transformações de organização do código legado. Esta atividade é realizada manualmente pelo Engenheiro de Software. Em seguida, o código legado é submetido a um transformador, que contém transformações desprovidas de padrão de substituição (RHS), com objetivo de armazenar na Base de Conhecimento, fatos e regras, com informações sobre a organização do código legado. Dentre estas transformações, destacam-se as utilizadas para: a) Identificar supostas classes através do reconhecimento de comandos de abertura e acesso aos arquivos de dados, estruturas de dados; b) Identificar supostos atributos, reconhecidos pelos campos dos arquivos de dados, comandos de acesso ao banco de dados, campos de estruturas de dados; c) Identificar supostas classes de interface. Em sistemas orientados a menus, cada tela de interação dá origem a uma suposta classe de interface e os objetos de interface dão origem a um suposto atributo da classe de interface; Em sistemas não orientados a menus, cada bloco de comandos do código legado, que não faz referência a arquivo de dados, é definido como um suposto método de uma suposta classe de interface. Esta suposta classe não possui objetos de interface e, portanto, não dá origem a nenhum suposto atributo; d) Identificar supostos métodos, de uma suposta classe, a partir das unidades de programas que podem ser procedimentos, funções ou blocos de comandos executados pelo disparo de um evento de interface ou pela chamada de outra unidade de programa, respeitando o escopo, dependência de dados e visibilidade do código legado. Os supostos métodos são classificados em construtores (c), quando alteram uma estrutura de dados, e observadores (o), quando somente consultam a estrutura de dados. Um suposto método que faz referência à somente um arquivo de dados, é relacionado como suposto método da suposta classe identificada para este arquivo. Se o suposto método não consulta nem modifica nenhum arquivo de dados, é relacionado com uma suposta classe de interface. Quando um suposto método refere-se a mais de uma suposta classe ele deve ser alocado usando os seguintes critérios[16]: Figura 3 – Estratégia de Reengenharia de Software usando Transformações (RST) Organizar Código Legado Transformações para Organizar o Código Legado Código Legado Organizado Descrições MDL do Projeto Baseado em Componentes Distribuídos Descrições MDL do Projeto Recuperado Transformações para Recuperar o Projeto em MDL Transformações para reimplementar o projeto numa linguagem executável Técnicas ER Linguagem executável alvo da reimplementação i Informações Disponívies Recuperar Projeto Reprojetar Reimplementar Reimplementar Projeto Baseado em ComponentesDistribuídos Projeto recuperado do Código Legado Técnicas DBCD Código Legado ES ES Draco MVCASE Novos Requisitos ES MVCASE MVCASEES ES Draco Sistema Implementado Sistema Implementado Draco Domínios no Draco Engenharia Reversa Base de Conhecimento Desenvolvimento Baseado em Componentes Distribuídos ER KB DBCD Modeling Domain LanguageMDL ES Engenheiro de Software Se um suposto método for construtor de uma suposta classe e observador de outra (oc), será alocado na suposta classe que faz referência como construtor; Se um suposto método for observador de uma suposta classe e construtor de várias (oc+), será alocado na primeira suposta classe que faz referência como construtor; Se um suposto método for observador de mais de uma suposta classe e construtor de apenas uma (o+c), será alocado na primeira suposta classe que faz referência como observador; Todas as unidades de programas candidatas a supostos métodos de uma mesma suposta classe são reunidas em um único arquivo; e) Identificar relacionamentos das supostas classes, através de variáveis e comandos que manipulam dados de um arquivo de dados. É verificado se um campo de um arquivo, identificado como chave, tem seus valores consultados e atribuídos a uma variável, e posteriormente o valor dessa variável é armazenado em campos de outro arquivo ou é utilizado para fazer busca em registros de outros arquivos. f) Identificar conexões de mensagens, a partir da interface do sistema, para definir os fluxos de execução de cada cenário de uso do sistema. Nos sistemas orientados a menus, parte-se de cada opção do menu para definir os diferentes cenários de uso do sistema. A Figura 4 mostra as transformações IdentifySelect e IdentifySupposedClass usadas para identificar as supostas classes e seus supostos atributos. A primeira transformação IdentifySelect reconhece o comando SELECT do Clipper que define uma área de dados, usada por arquivos de extensão .dbf. No ponto de controle POST-MATCH cria-se um fato na Base de Conhecimento que relaciona esta área de dados com uma suposta classe. A transformação IdentifySupposedClass reconhece o comando USE do Clipper que dá origem a uma suposta classe. O ponto de controle LHS (1) especifica a regra de produção statements do parser Clipper que reconhece o comando USE, que identifica um arquivo de dados indexado. A metavariável FileName do tipo iden, armazena o nome do arquivo. Os índices são armazenados na área apontada pela metavariavel Indexes do tipo iden. No ponto de controle POST-MATCH (2), inicialmente recupera-se o fato SupposedClass com as informações sobre a área de dados do arquivo. Em seguida (3), o nome do arquivo é armazenado na variável CurrentClass. Este nome é usado para localizar o arquivo com extensão .dbf. Em (4) é criado o fato SupposedClass na Base de Conhecimento, associando a área do arquivo com a CurrentClass, que tem o mesmo nome do arquivo. Em (5) são identificados os atributos de cada campo do arquivo .dbf, como nome (AttribName), tipo (AttribType), tamanho (AttribSize) e parte decimal (AttribDec). Em (6) é criado o fato SupposedAttribute relacionando as informações identificadas em (5) com a suposta classe. Outras transformações são usadas para identificar supostas classes de interface, supostos métodos, relacionamentos entre supostas classes e o fluxo de execução do código legado. Além dos fatos sobre supostas classes, supostos atributos e métodos outros fatos contendo informações sobre o código legado também são armazenados na Base de Conhecimento. Numa segunda etapa, do passo Organizar Código Legado, com base nas informações coletadas, na Base de Conhecimento, pelo primeiro transformador Intradomínio, aplica-se o segundo transformador Intradomínio, que segmenta o código legado em supostas classes com seus supostos atributos, métodos e relacionamentos. Concluído este passo, tem-se o código legado organizado seguindo os princípios de orientação a objetos. 6.2. Recuperar Projeto No segundo passo, Recuperar Projeto, obtém-se o projeto do código legado. Primeiramente, o Engenheiro de Software parte do código legado organizado e, novamente com o auxíliodo ST Draco, obtém as especificações UML do projeto do código legado. As especificações UML, geradas pelo ST Draco, são armazenadas em descrições na linguagem de modelagem MDL (Modeling Domain Language). Os comportamentos dos supostos métodos, separados em arquivos no passo Organizar Código Legado, e cujos protótipos já foram criados nas respectivas classes, são transformados diretamente para Java. A Base de Conhecimento é consultada para a criação das classes, atributos, protótipos dos métodos e relacionamentos entre as classes. A Figura 5 mostra uma transformação Interdomínios, que cria as classes e gera suas descrições na linguagem MDL. O ponto de controle LHS (1) especifica a regra de produção program que reconhece um programa em Clipper. As metaváriaveis ProgName e Elements dos tipos ID e prog_elements, respectivamente, armazenam o nome e o corpo do programa Clipper, para que os supostos métodos sejam reconhecidos, dando origem às correspondentes especificações, que contêm os supostos métodos, que dão origem às operações de uma classe. No ponto de controle POST-MATCH consulta-se os fatos SupposedClass (2) na Base de Conhecimento, para definir uma classe que conterá os supostos métodos. O fato Class (3) gera esta classe. Em seguida consulta-se os fatos SupposedAttribute Figura 4 – Transformação que identifica as supostas classes e seus supostos atributos (4), desta classe, na Base de Conhecimento. Para cada suposto atributo tem-se o padrão de substituição na linguagem MDL, dando origem a um atributo da classe. Da mesma forma que os supostos atributos, procede-se com os protótipos dos supostos métodos de cada suposta classe. Parte-se dos fatos sobre cada suposto método (5) e gera-se o correspondente protótipo da operação em MDL. Em seguida, o Engenheiro de Software, usando a ferramenta MVCase, importa as descrições MDL para obter o projeto recuperado do código legado. O projeto recuperado é representado pelos Modelos de classes, com seus atributos, métodos e relacionamentos, e pelos Modelos de Interações. Os Modelos de Interações são representados em Diagramas de Seqüência que definem os fluxos de execução do sistema, com suas conexões de mensagens. 6.3. Reprojetar No terceiro passo, Reprojetar, o Engenheiro de Software com o auxílio da ferramenta MVCASE e de técnicas DBC Distribuídos, faz o reprojeto orientado a componentes distribuídos do projeto recuperado do código legado, obtendo um novo projeto baseado em componentes distribuídos. O projeto recuperado serve como base para a especificação e projeto dos componentes. Este passo é direcionado pelo método de desenvolvimento Catalysis com seus três níveis: Domínio do Problema, Especificação dos Componentes e Projeto Interno dos Componentes. Para que se tenha uma idéia melhor deste passo apresenta-se a seguir detalhes do método Catalysis, para a criação do componente Cliente. 6.3.1. Domínio do Problema Neste nível, preocupa-se com “o que” o sistema deve fazer para solucionar o problema. São identificados os tipos de objetos e ações, agrupando-os em diferentes visões por áreas de negócio. O Engenheiro de Software modela os Modelos de Casos de Uso, indicando o relacionamento dos atores com o sistema, dispensando detalhes que não são relevantes para o contexto. A Figura 6 mostra o ator Customer interagindo com o sistema através do caso de uso AddServiceOrder. 6.3.2. Especificação dos Componentes Neste nível, refinam-se as especificações do nível anterior, enfatizando-se a identificação, o comportamento e as responsabilidades dos componentes. Novos modelos, mais detalhados, são obtidos, porém ainda sem se preocupar com a implementação. A partir dos Modelos de Caso de Uso, são construídos os Diagramas de Seqüência, que têm por objetivo mostrar os cenários de execução das operações ao longo do tempo. No caso da estratégia, os diagramas de seqüência obtidos no passo Recuperar Projeto são refinados, e novos diagramas podem ser construídos para atender novos requisitos adicionados ao projeto. A Figura 7 mostra o Diagrama de Sequencia com as interações do ator Customer com os objetos do sistema. 6.3.3. Projeto Interno dos Componentes Neste nível, faz-se o projeto interno dos componentes, dando ênfase às suas implementações e distribuições físicas. No caso da estratégia, a tecnologia EJB é utilizada para a construção dos componentes a partir das classes obtidas no passo Recuperar Projeto. Para refinar os modelos, o Engenheiro de Software pode Figura 5 – Transformação que gera a descrição MDL de uma classe e de seus atributos e métodos Figura 6 – Modelo de Caso de Uso Figura 7 – Diagrama de Sequência alterar o nome das classes, seus atributos e métodos tornando-os mais significativos. A Figura 8 mostra o projeto interno do componente CustomersEJB. A partir do Diagrama de Seqüência e Caso de uso são criadas a Interface Remote, que possui métodos responsáveis pelas regras de negócio, e a Interface Home, que possui métodos para referenciar e manter o objeto remoto. No caso do bean Customers tem-se a classe CustomersEJB que implementa a interface EJB e disponibiliza a Interface Remote Customers, que estende Interface EJBObject, e a Interface CustomersHome que estende a interface EJBHome. 6.4. Reimplementar Finalmente, no quarto passo da estratégia, faz-se a reimplementação do sistema reprojetado. A reimplementação pode ser realizada através de transformações das descrições MDL do reprojeto, com o auxílio do sistema de transformação Draco ou através da ferramenta MVCASE que gera código automaticamente a partir dos modelos de objetos e componentes do reprojeto. Segue-se a apresentação de um estudo de caso que mostra o uso da estratégia proposta. 7. ESTUDO DE CASO Trata-se de um sistema para Oficina Auto-Elétrica e Mecânica que controla os serviços executados nos veículos e o estoque das peças utilizadas. O cliente vai até a oficina para solicitar um serviço em seu veículo. Um cliente pode ter diversos veículos. O mesmo veículo pode voltar à oficina diversas vezes, sendo elaborada, em cada uma delas, uma Ordem de Serviço distinta. Essa Ordem de Serviço contém dados do cliente, do veículo e dos reparos a serem feitos. Quando o veículo é consertado, a Ordem de Serviço é completada, introduzindo-se as peças utilizadas e a mão-de-obra executada. Muitas vezes, o reparo pode exigir peças não existentes no estoque, que são adquiridas fora da oficina mecânica e que também participam da Ordem de Serviço. O registro dessas peças é importante para o gerente da oficina, pois essas são candidatas a serem estocadas no futuro. Os possíveis modelos de veículos devem ser cadastrados pelo sistema, pois são utilizadas tabelas para cobrança de serviços, tanto elétricos como mecânicos, de acordo com o modelo de veículo. Esse sistema [18] foi desenvolvido em 1990 e tem cerca de 20.000 linhas de código Clipper. Segue-se uma apresentação de cada passo da estratégia para a reengenharia deste sistema 7.1. Organizar Código Legado Inicialmente reuniu-se as informações disponíveis sobre o código legado, no caso apenas o código legado, e elaborou-se a relação CHAMA/CHAMADO, para determinar a seqüência de programas a serem submetidos ao transformador ClipperToKB, que organiza o código legado segundo os princípios da Orientação a Objetos. A Figura 9 mostra à esquerda um programa, Ostela1.prg (1), do código legado Clipper. Baseado nos comandos SELECT e USE reconhece-se uma suposta classe, e cria-se na Base de Conhecimento (3), o fato SupposedClass, e para cada suposto atributo cria-se um fato SupposedAttribute. E através do programa Catproc.prg (2) foram identificados os procedimentos CLEAR e WARNING, que não fazem referência a nenhum arquivo de dados. Quandoprocedimentos como esses são identificados pelo transformador, eles são relacionados na Base de Conhecimento como procedimentos de interface através do fato “SupposedMethod” e seu parâmetro “SystemInterface”. Após identificar as supostas classes, seus supostos atributos e métodos um outro transformador Intradomínio, ClipperKbToClipper, é aplicado para segmentar o código segundo as supostas classes, atributos, métodos e relacionamentos. A Figura 10 mostra à esquerda (1) o programa Customer.prg e à direita (2) seu correspondente código organizado. O código Figura 9 – Armazenamento de fatos na Base de Conhecimento Figura 10 - Segmentação do código legado segundo os princípios da Orientação a Objetos Figura 8 – Projeto Interno do Componente CustomersEJB permanece na mesma linguagem, porém com características da Orientação a Objetos. No caso, o código foi segmentado nas funções CustomerOpen(), CustomerInit() e CustomerFind(). Da mesma forma procede-se em todo o código legado do sistema, obtendo-se no final deste passo o código segmentado e organizado em supostas classes, atributos, métodos e relacionamentos. 7.2. Recuperar Projeto Neste passo aplicam-se as transformações ClipperToMDL no código legado organizado para gerar as descrições MDL, que permitem recuperar o Projeto do código legado. A Figura 11 apresenta um exemplo de transformação onde são geradas as especificações de uma classe, com suas operações e atributos, na linguagem de modelagem UML. À esquerda tem-se o código legado Clipper organizado e à direita tem-se a descrição MDL gerada, correspondente à especificação UML. Cada suposta classe, suposto método, e suposto atributo dão origem, respectivamente, à especificação de uma classe, operação, e atributo em UML, gerando a respectiva descrição em MDL. Por exemplo, a suposta classe identificada como Customer (1) dá origem à Class “Customer”. O suposto método identificado como PROCEDURE proc40 (2), dá origem à Operation “proc40”, da classe “Customer”. Os supostos atributos vcRG (3) e Name (4) dão origem aos ClassAttributes “vcRG” e “Name”, respectivamente. A base de conhecimento RBCD.kb é consultada para obter os fatos e regras sobre as supostas classes, atributos e métodos. No caso pode-se ver ainda que o comportamento de proc40 do Clipper, foi transformado diretamente para Java, que é a linguagem alvo da re- implementação. Assim, o protótipo de um método em uma classe é descrito em MDL, e seu corpo, é descrito diretamente em Java. A geração de código para reimplementar o sistema em Java, fica mais fácil uma vez que já se tem pronto os códigos dos métodos. Depois de concluídas as transformações de Clipper para MDL, o Engenheiro de Software pode importar as descrições MDL na MVCASE para obter o projeto recuperado do código legado. O projeto recuperado é representado por técnicas UML, em Modelos de classes e de Interações. A Figura 12 mostra parte do Modelo de classes recuperado através das descrições MDL. O comportamento dos métodos em cada classe foi obtido pela transformação direta do comportamento dos supostos métodos do código legado Clipper, organizado em unidades de programas, para a linguagem Java, alvo da reimplementação do sistema. Para obter a transformação utilizou-se o transformador ClipperToJava. 7.3. Reprojetar Neste passo o Engenheiro de Software pode reprojetar o projeto recuperado, por exemplo usando componentes distribuídos. Seguindo o método Catalysis pode-se refinar os modelos recuperados para obter um novo projeto reestruturado com componentes distribuídos. Por exemplo, refinando o Modelo de classes da Figura 12 pode-se obter o Modelo de classes de componentes da Figura 13. No caso o objeto Customer foi transformado no componente Customer, segundo a tecnologia EJB. Foram criadas a classe persistente CustomerEJB e suas interfaces CustomerHome e Customer, que reutilizam as classes EntityBean, EJBHome e EJBObject da biblioteca Java/EJB importada na MVCASE. 7.4. Reimplementar A reimplementação pode ser realizada por transformação, usando o ST Draco ou diretamente pelo gerador de código Java da MVCASE. Por exemplo, usando o ST Draco, aplica-se o transformador Interdomínio MDLToJava, que transforma as descrições MDL em código Java. A Figura 14 mostra à esquerda a descrição MDL e à direita o correspondente código Java/EJB gerado pelas transformações. Cada descrição MDL de uma classe ou interface dá origem a um Figura 12 – Modelo de classes recuperado na MVCASE Figura 13 – Modelo de classes de componentes EJB Figura 11 – Geração da descrição MDL de uma classe arquivo na linguagem Java, no caso CustomerEJB.java, Customer.java e CustomerHome.java. A reimplementação pode também ser feita através da ferramenta MVCASE que gera o código, conforme mostra a Figura 15. A geração do código EJB baseia-se no Modelo de classes dos componentes e no Modelo de componentes, especificados no reprojeto. Se o Engenheiro de Software mantiver o comportamento dos métodos em Java, o código gerado poderá ser mais completo, caso contrário, tem-se apenas o código das estruturas das classes com seus atributos e protótipo dos métodos. A Figura 16 mostra a arquitetura para execução do sistema reimplementado. Na camada (1) têm-se as aplicações Clientes, que podem ser JSPs ou Servlets em um Browser, via http usando um Servidor Web um Frame ou Applet, como aplicação Stand Alone. As aplicações Clientes acessam, via RMI, os componentes disponíveis no servidor J2EE, na camada Regras de Negocio (2). Os serviços de Banco de Dados ficam na camada (3), e podem ser acessados pelos componentes, através da comunicação do Servidor J2EE com o Servidor de Banco de Dados. Nesta arquitetura os componentes podem ser distribuídos, residindo em diferentes computadores. O código gerado pode ser executado e os resultados da execução são analisados pelo Engenheiro de Software para verificar se o sistema reconstruído atende os requisitos recuperados do código legado e os adicionados no reprojeto. Caso não atenda, pode-se retornar aos passos da estratégia para corrigir possíveis erros e gerar o código novamente. A funcionalidade do sistema legado é mantida no sistema reimplementado com a vantagem de facilitar a manutenção, uma vez que o código está organizado e encapsulado em componentes. Como as transformações foram construídas preservando a semântica da linguagem origem na linguagem alvo da implementação, as falhas podem ser do próprio código legado ou das alterações introduzidas no reprojeto. O tempo total para transformar o sistema de Auto-Elétrica e Mecânica de Clipper para Java, considerando a carregamento da Base de Conhecimento e organização do código, foi de 1 hora e 46 minutos, conforme mostra a tabela da Figura 17, com os tempos de execução das transformações de cada programa do sistema. Nesta experiência foi utilizada a MVCASE apenas para recuperar o projeto do código legado. Numa segunda experiência, a MVCASE foi usada tanto para recuperar o projeto quanto para gerar código Java, sem utilizar o transformador MDLToJava. Este tempo poderia se repetir para outros sistemas do mesmo porte. É verdade que este tempo não levou em conta o tempo gasto para construção dos domínios e das transformações, que normalmente leva cerca de 6 meses, devido a complexidade e a necessidade de um conhecimento profundo sobre os domínios a serem construídos. Contudo, a grande vantagem vem da reutilização das transformações em outros sistemas, quando então o tempo será de apenas algumas horas, enquanto que na reengenharia manual poderia levar meses com uma equipe de várias pessoas. 8. CONCLUSÃO Este artigo apresentou uma estratégia para transformar código fonte de sistemas legados, orientados a procedimentos, para sistemasorientados a componentes distribuídos, usando Figura 14 – Reimplementação usando Transformações Figura 15 – Código gerado através da MVCASE Figura 16 – Arquitetura do sistema reimplementado Figura 17 - Tempo de transformação do sistema de Auto- Elétrica e Mecânica transformações, para serem executados em plataformas modernas de hardware e software. No contexto da estratégia proposta, os componentes de software são utilizados como blocos de reconstrução de sistemas legados, permitindo sua distribuição em diferentes plataformas de hardware e software. A estratégia cobre todo o ciclo da reengenharia de um sistema procedural, destacando-se a recuperação do projeto do código legado permitindo o reprojeto orientado a componentes distribuídos, em uma ferramenta CASE, com reimplementação semi-automática em uma linguagem orientada a objetos, através de uma ferramenta CASE ou através de transformações. As funcionalidades do sistema legado são mantidas no sistema reimplementado, com a vantagem de facilitar a manutenção, uma vez que o código está organizado em classes e objetos. Além disso, o uso da tecnologia EJB incorpora certa flexibilidade e uma estrutura organizada em componentes, que podem ser reutilizados diretamente em novos projetos com pequenas adaptações, como no caso da troca do Banco de Dados.. Como o ST Draco é orientado a domínios, a estratégia pode ser aplicada a sistemas legados de diferentes domínios de linguagens como, por exemplo, Pascal, Cobol e outras. A linguagem alvo também pode ser outra diferente de Java como, por exemplo, Object Pascal e C++. Embora a ferramenta CASE possa também gerar a implementação do sistema a partir de suas especificações a estratégia fica mais genérica e flexível deixando esta tarefa para o sistema de transformação onde se pode variar a linguagem alvo da reimplementação. Outros dois estudos de casos foram realizados aplicando a estratégia em duas empresas. A primeira [9] aplicou a estratégia em um sistema legado implementado em Progress4GL, obtendo um novo sistema em Java. Esse sistema possui cerca de 1500 programas fontes, totalizando em torno de 1.500.000 linhas de código em Progress. A Segunda [8] aplicou a estratégia em um sistema implementado em DataFlex Procedural, obtendo um sistema em Visual DataFlex. Este sistema possui cerca de 1.900 programas totalizando 5.3 milhões de linhas de código. Esses estudos mostraram a viabilidade de uso do Draco-PUC, com o auxílio dos scripts de transformação do DDE, por pessoas que não participaram do desenvolvimento das gramáticas e transformadores. 9. Referências [1] GAMMA, E. et al. Design Patterns. Elements of Reusable Object-Oriented Software. Ed. Addison-Wesley. USA.1995. [2] NEIGHBORS, J.M. The Draco approach to Constructing Software from Reusable Components. IEEE Transactions on Software Engineering. v.se-10, n.5, pp.564-574, September, 1984. [3] JACOBSON, I. et all. Software Reuse – architecture process and organization for business success. Ed. Addison-Wesley, New York, 1997. [4] Reasoning Systems Incorporated. Refine User’s Guide, Reasoning Systems Incorporated, Palo Alto, 1992. [5] WILE, D. Popart: Producer of Parsers and Related Tools System Builders Manual. Technical Report, USC/Information Sciences Institute, 1993. [6] FUKUDA, A. P. Refinamento Automático de Sistemas Orientados a Objetos Distribuídos. São Carlos/SP, 2000. Dissertação de Mestrado. Universidade Federal de São Carlos. [7] JESUS, E.S. Engenharia Reversa de Sistemas Legados Usando Transformações. São Carlos/SP, 2000. Dissertação de Mestrado. Universidade Federal de São Carlos. [8] NOGUEIRA, A. R. ,“Transformação de DataFlex Procedural para Visual DataFlex Orientado a Objetos reusando um Framework”, São Carlos/SP, 2002, Dissertação de Mestrado. Universidade Federal de São Carlos. [9] NOVAIS, E. R. A.; “Reengenharia de Software Orientada a Componentes Distribuídos”, São Carlos/SP, 2002, Dissertação de Mestrado, Universidade Federal de São Carlos. [10] PRADO, A.F. Estratégia de Engenharia de Software Orientada a Domínios. Rio de Janeiro-RJ, 1992. Tese de Doutorado. Pontifícia Universidade Católica. 333p. [11] BARRÉRE T. S.; CASE com Múltiplas Visões de Requisitos de Software e Implementação Automática em Java - MVCASE, 1999. Dissertação de Mestrado. Universidade Federal de São Carlos. [12] PRADO, A. F., LUCRÉDIO, D; Ferramenta MVCASE - Estágio Atual: Especificação, Projeto e Construção de Componentes - Sessão de Ferramentas do XV Simpósio Brasileiro de Engenharia de Software - SBES'2001. Rio de Janeiro-RJ, Brasil. 3 – 5 de Outubro, 2001. [13] BOOCH, G. et al. The Unified Modeling Language – User Guide. USA: Addison Wesley, 1999. [14] Enterprise Java Beans technology, Sun Microsystems. URL: http://java.sun.com/products/ejb/index.html, 2001. [15] D’SOUZA, D. and A. Wills, “Objects, Components and Frameworks with UML–The Catalysis Approach”, USA: Addison Wesley, 1995. [16] PENTEADO, R.D. Um Método para Engenharia Reversa Orientada a Objetos. São Carlos-SP, 1996. Tese de Doutorado. Universidade de São Paulo. 251p. [17] PRESSMAN, R. S. Engenharia de Software. Makron Books: São Paulo, 1995. [18] R. Spence, Clipper 5.2, São Paulo, Makron books, 1994.
Compartilhar