Para ilustrar o contexto deste trabalho, esta pesquisa utilizou um sistema descrito e implementado em [Arr01], que fornece descrições de casos de uso, diagramas UML e código fonte da aplicação. Trata-se de um sistema de apropriação de horas de funcionários chamado Sistema de Cartão Ponto (Timecard). O objetivo do sistema é apoiar o registro de horas em determinadas atividades, chamadas de Códigos de Débito (charge code). Neste sistema, os usuários podem realizar a manutenção desses códigos, a manutenção de empregados, bem como o registro de horas nesses códigos. Para ilustrar melhor o universo de discurso, a Figura 3.2 apresenta o Modelo de Domínio com os principais conceitos da aplicação e seus relacionamentos.
Figura 3.2 – Modelo de Domínio do Sistema de Cartão Ponto [Arr01].
Para compreender as principais funcionalidades oferecidas pelo sistema, o diagrama de casos de uso é apresentado na Figura 3.3. O exemplo seguido neste trabalho se refere ao caso de uso Registrar Horas, cujo fluxo principal se encontra descrito na Figura 3.4.
Durante a evolução do software, devido a uma necessidade de negócio, surge um requisito de mudança formalizado em um RdM. Este requisito caracterizado como mantenção evolutiva consiste em alterar o sistema a partir da declaração representada pela Figura 3.5.
Para entender um pouco o desafio em avaliar o impacto dessa mudança no código fonte, é necessário considerar aspectos técnicos bem como a complexidade do sistema. Com relação à tecnologia utilizada, o sistema foi desenvolvido em Java utilizando
Enterprise Java Beans (EJB), versão 1.1, o qual faz parte da especificação Java 2 Enterprise Edition (J2EE). O código é estruturado pelos seguintes componentes: Entity bean, Home interface, Session bean, Remote interface, Implementation, Deployment descriptor, Bean-managed persistence e Container-managed persistence.
Figura 3.3 – Diagrama de Casos de Uso do Sistema de Cartão Ponto traduzido [Arr01].
Fluxo de eventos principal: Empregado registra suas horas. Passo # Ação
1 O empregado visualiza as horas previamente entradas para o período atual.
2 O empregado seleciona um código de débito dentre os disponíveis, organizados por clientes e projeto.
3 O empregado seleciona um dia na semana corrente.
4 O empregado informa horas trabalhadas como um número decimal positivo. 5 As horas são armazenadas e visualizadas em qualquer acesso subsequente.
Figura 3.4 – Fluxo principal do caso de uso Registrar Horas [Arr01].
Durante o registro de horas, o usuário poderá informar horas para o mês corrente até a data atual.
Figura 3.5 – Requisito de mudança.
Com o objetivo de avaliar a complexidade do código no momento de analisar o impacto da mudança, foram extraídas algumas métricas apresentadas nas Tabelas 3.1 e 3.2. Estas métricas se tornam relevantes para analisar o escopo total da aplicação bem como a quantidade de código fonte passível de inspeção.
Tabela 3.1 – Estrutura do sistema.
Quantidade
de Pacotes Quantidade de Classes Quantidade de Associações Generalizações Quantidade de
Tabela 3.2 – Análise de Linhas de Código (LoC) do Sistema de Cartão Ponto.
Linguagem Arquivos Linhas em Branco Linhas de Comentários Linhas de Código
Java 75 890 721 3414
HTML 5 37 28 117
XML 1 0 0 12
DOS Batch 2 0 0 5
Pela análise das Tabelas 3.1 e 3.2, identificam-se 75 classes organizadas em 12 pacotes. Para realizar a análise de impacto da mudança solicitada, a Seção 2.1.3 apresenta algumas estratégias.
A primeira opção é a força bruta, navegando no programa, abrindo e fechando arquivos relacionados. Os desenvolvedores geralmente alteram o código para avaliar o impacto na aplicação durante sua execução. Esta opção é uma atividade manual fortemente baseada na experiência. No pior caso, o desenvolvedor deveria considerar as 3414 linhas de código, incorrendo em um exercício de tentativa e erro.
Uma alternativa à navegação em um programa é apoiar a análise na especificação do software. Para tanto, é necessário que a documentação do software esteja atualizada. De posse destes documentos, pode-se navegar por todos os modelos produzidos para analisar o impacto. Considerando a UML como referência, esta atividade inclui investigar (1) Diagramas Estruturais, como Diagrama de Classes, Objetos, Componentes, Infraestrutura, Pacotes, etc., e (2) Diagramas Comportamentais, como Diagramas de Atividades, Casos de Uso, Máquina de Estados, Sequência, Comunicação, etc. Uma vez identificado os impactos nos modelos, cada elemento deve estar mapeado adequadamente com as estruturas de código fonte para, então, realizar a análise de impacto.
O uso de matrizes de rastreabilidade convencionais pode apoiar a análise de impacto, relacionando requisitos com estruturas de código. Devido à granularidade do caso de uso, é possível identificar que um conjunto de classes esteja relacionado a um requisito. Não se pode, porém, considerar aspectos mais específicos do comportamento como, no exemplo em questão, o impacto específico em métodos e atributos. Além dessa restrição, deve-se avaliar se os relacionamentos entre requisitos e classes do sistema estão completos e corretos.
Por último, a análise de dependência é uma alternativa viável quando se refere a código fonte. Esta análise pressupõe navegar pelos métodos através do grafo de
chamadas. Para tanto, é necessário conhecer os métodos e considerar o impacto um a um. Com o objetivo de melhor entender a dinâmica da análise de dependência e particionamentos, a seguir será apresentada a ferramenta JRipples2 descrita em [Buc05, Pet09]. Esta ferramenta é utilizada para a análise de impacto e propagação de mudanças onde dependências transitivas são avaliadas.
O método de grafo de chamadas, conforme ilustrado pela Figura 3.6, é utilizado pela ferramenta JRipples para analisar as dependências. Neste exemplo, são apresentados os tipos de dependência que a classe RecordTimeWorkflowBean possui com outras classes do projeto. É navegando pelo encadeamento dessas dependências que o grafo de chamadas é executado.
Figura 3.6 – Análise de dependência manual usando JRipples.
A ferramenta JRipples, em oposição às abordagens anteriores, tem cobertura em código e sistematiza a atividade de análise. A ferramenta analisa a dependência dos métodos do programa e solicita ao usuário abrir cada classe dependente indicada pela ferramenta. O usuário abre a classe, analisa o código fonte e decide se é necessária alguma alteração. Caso seja necessário, ele marca na ferramenta a necessidade de revisão e a ferramenta recupera todas as classes relacionadas a este impacto identificado. Caso contrário, a ferramenta ignora e apresenta as próximas classes dependentes. O uso da ferramenta para a análise de impacto está ilustrado em detalhes no Apêndice 2.
Seguindo o exemplo apresentado para a mudança proposta (Figura 3.5), são necessárias alterações na classe de controle RecordTimeWorkflowBean e suas interfaces RecordTimeWorkflow e RecordTimeWorkflowHome, bem como na classe de fronteira RecordTimeServlet para validação da data. Para localizar apenas as classes utilizando a ferramenta JRipples, foi necessário analisar 22 diferentes classes (aproximadamente 30%) que equivalem a 1681 linhas de código (aproximadamente 50%), correndo o risco de uma análise equivocada devido à dependência de interpretação do desenvolvedor quanto ao código alterado.
Avaliando as abordagens existentes para a análise de impacto, percebe-se que ainda é uma atividade manual e fortemente baseada na percepção humana, bem como na confiança em uma documentação de apoio.
Conforme apresentado, mudanças são decorrentes de necessidades de negócio. Pela análise do requisito de mudança definido na Figura 3.5, percebe-se que esta necessidade se relaciona a alguns conceitos de domínio apresentados na Figura 3.2. Dentre estes conceitos, pode-se considerar “usuário” (user) e “registro de horas” (time record), bem como algumas propriedades desses conceitos como “registrar”(register) e “horas” (hours).