Buscar

Definicaodeteccaodesign_Melo_2020

Prévia do material em texto

Universidade Federal do Rio Grande do Norte
Instituto Metrópole Digital
Programa de Pós-graduação em Engenharia de
Software
Mestrado Profissional em Tecnologia da
Informação
Definição e Detecção de Design Smells em
Aplicações de Processamento em Lotes
Utilizando Spring Batch Framework
Deyvisson Carlos Borges de Melo
Natal-RN
Agosto de 2020
Deyvisson Carlos Borges de Melo
Definição e Detecção de Design Smells em Aplicações de
Processamento em Lotes Utilizando Spring Batch
Framework
Dissertação apresentada ao Programa de Pós-
graduação em Tecnologia da Informação da
Universidade Federal do Rio Grande do Norte
como requisito parcial para a obtenção do
grau de Mestre em Tecnologia da Informação.
Universidade Federal do Rio Grande do Norte – UFRN
Instituto Metrópole Digital – IMD
Programa de Pós-Graduação em Engenharia de Software
Orientador: Dr. Eiji Adachi Medeiros Barbosa
Natal/RN
2020
Melo, Deyvisson Carlos Borges de.
 Definição e detecção de design smells em aplicações de
processamento em lotes utilizando spring batch framework /
Deyvisson Carlos Borges de Melo. - 2020.
 86f.: il.
 Dissertação (Mestrado) - Universidade Federal do Rio Grande
do Norte, Instituto Metrópole Digital, Mestrado Profissional em
Tecnologia da Informação, Natal, 2020.
 Orientador: Dr. Eiji Adachi Medeiros Barbosa.
 1. Aplicações batches - Dissertação. 2. Arquitetura de
software - Dissertação. 3. Code smells - Dissertação. 4. Design
smells - Dissertação. 5. Processamento em lotes - Dissertação.
I. Barbosa, Eiji Adachi Medeiros. II. Título.
RN/UF/BCZM CDU 004.4
Universidade Federal do Rio Grande do Norte - UFRN
Sistema de Bibliotecas - SISBI
Catalogação de Publicação na Fonte. UFRN - Biblioteca Central Zila Mamede
Elaborado por Raimundo Muniz de Oliveira - CRB-15/429
Agradecimentos
A Deus, por possibilitar minha jornada de constante evolução, provendo fé, capaci-
dade, conhecimento e força de vontade.
À minha mãe e esposa, por representarem minha fortaleza e alicerce servindo de
base psicológica e emocional em minha vida.
Ao professor Eiji Adachi, por me ajudar no retorno ao ambiente acadêmico e por
sua importante orientação para elaboração desse trabalho.
À DATAPREV, por viabilizar minha participação no programa de mestrado profis-
sional.
Resumo
Para atender as constantes mudanças de requisitos e necessidades de novas funcionalidades,
os sistemas de software permanecem sempre em um estado de constante evolução. O
controle do processo de evolução e manutenção de um software é crucial e uma das fases
mais complicadas do desenvolvimento de software. Se esse controle não for gerenciado,
os sistemas correm o risco de degradação de importantes atributos de qualidade que
consequentemente afetam diretamente o grau de manutenibilidade das aplicações. Fatores
como inexperiência, falta de conhecimento e pressões em relação ao tempo de conclusão de
tarefas levam a adoção de más práticas de design de software e são a origem dos Design
Smells. Para se obter um melhor controle do processo de evolução e manutenção de um
software, é importante saber identificar a ocorrência de Design Smells nos projetos, e novos
estudos indicam que a utilização de informações específicas do contexto da aplicação, como
a natureza dos programas ou papeis arquiteturais utilizados, podem influenciar no processo
de detecção e na identificação de problemas que só existem no contexto estudado. Este
trabalho realiza um estudo para a definição e identificação de Design Smells específicos ao
contexto das aplicações de processamento em lotes, e propõe a definição de um catálogo
de 7 Design Smells e a implementação de uma ferramenta para automatizar o processo
de detecção. A ferramenta implementada foi utilizada em um estudo de caso em que os
códigos de 40 sistemas foram analisados. Nesse estudo, observou-se que os smells específicos
ao contexto das aplicações de processamento em lotes afetaram quase 20% das classes e
mais que 30% das linhas de código dos sistemas analisados. Também foi possível observar,
por meio da aplicação da ferramenta em várias versões de dois sistemas, que o número de
smells se manteve constante ao longo das versões, e em alguns casos até cresceu. O que
pode evidenciar a falta de conhecimento da existência dos smells e dos impactos negativos
que podem incorporar nas aplicações.
Palavras-chave: aplicações batches. arquitetura de software. code smells. design smells.
processamento em lote. spring batch.
Abstract
To meet the constant changes of requirements and needs for new features, software
systems always remain in a state of constant evolution. The control of the software
evolution and maintenance process is crucial and one of the most complicated phases of
software development. If this control is not managed, systems are at risk of degradation of
important quality attributes, that consequently directly affect the degree of maintainability
of applications. Factors such as inexperience, lack of knowledge and pressure in relation
to the time to complete tasks lead to the adoption of bad practices of software design
and are the origin of Design Smells. In order to obtain a better control of the software
evolution and maintenance process, it is important to know how to identify the occurrence
of Design Smells in projects, and new studies indicate that the use of information specific
to the context of the application, such as the nature of the programs or architectural
roles used, can influence the detection process and the identification of problems that
only exist in the studied context. This work carries out a study to define and identify
Design Smells specific to the context of batch applications, and proposes the definition of a
catalog with 7 Design Smells and the implementation of a tool to automate the detection
process. The implemented tool was used in a case study in which the codes of 40 systems
were analyzed. In this study, it was observed that smells specific to the context of batch
processing applications affected almost 20% of the classes and more than 30% of the lines
of code of the systems analyzed. It was also possible to observe, through the application of
the tool in several versions of two systems, that the number of smells remained constant
throughout the versions, and in some cases it even grew. What can evidence the lack
of knowledge about the existence of the smells and the negative impacts that they can
incorporate in the applications.
Keywords: batch applications. software architecture. code smells. design smells. batch
processing. spring batch.
Lista de ilustrações
Figura 1 – Etapas do processo de migração tecnológica do CV3. . . . . . . . . . . 14
Figura 2 – Exemplo básico de uma aplicação de processamento em lotes. . . . . . 19
Figura 3 – Arquitetura de referência para aplicações de processamento em lotes. . 20
Figura 4 – Exemplo de diagrama de sequência UML da execução do processamento
em lotes utilizando a arquitetura de referência. . . . . . . . . . . . . . . 22
Figura 5 – Divisão do catálogo de Smells por atributos de qualidade afetado. . . . 29
Figura 6 – Ilustração do Global Processor . . . . . . . . . . . . . . . . . . . . . . . 30
Figura 7 – Estratégia de detecção para Global Processor . . . . . . . . . . . . . . 31
Figura 8 – Estratégia 01 de refatoração para Global Processor . . . . . . . . . . . 32
Figura 9 – Estratégia 02 de refatoração para Global Processor . . . . . . . . . . . 32
Figura 10 – Exemplo de um Item Reader afetado pelo Brain Reader . . . . . . . . 33
Figura 11 – Estratégia de detecção para o Brain Reader . . . . . . . . . . . . . . . 34
Figura 12 – Estratégia de refatoração para o Brain Reader . . . . . . . . . . . . . . 35
Figura 13 – Estratégia de detecção para o Brain Processor . . . . . . . . . . . . . . 36
Figura 14 – Estratégia de refatoração para o Brain Processor . . . . . . . . . . . . 37
Figura 15 – Estratégia de detecção para o Brain Writer . . . . . . . . . . . . . . . 38
Figura 16 – Estratégiade refatoração para o Brain Writer . . . . . . . . . . . . . . 39
Figura 17 – Exemplo de aplicação batch sem ocorrência de consultas na fase de
processamento. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Figura 18 – Exemplo de aplicação batch com ocorrência de consultas na fase proces-
samento. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Figura 19 – Estratégia de detecção para o Readaholic Component. . . . . . . . . . . 41
Figura 20 – Impacto causado pelo Amateur Writer com a inclusão de 10.000 requi-
sições de escrita. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Figura 21 – Estratégia de detecção do Amateur Writer . . . . . . . . . . . . . . . . 43
Figura 22 – Refatoração de um Amateur Writer utilizando a composição de Item
Writers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Figura 23 – Step de um processamento em lotes afetado pelo Improper Communication. 44
Figura 24 – Estratégia de detecção para o Smell Improper Communication. . . . . 45
Figura 25 – Refatoração para o Smell Improper Communication do exemplo da
figura 23. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Figura 26 – Fluxo de execução da ferramenta SBSD . . . . . . . . . . . . . . . . . 49
Figura 27 – Diagrama de classes do componente de métricas da ferramenta SBSD. . 50
Figura 28 – Diagrama de classes do componente de dependências da ferramenta
SBSD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Figura 29 – Diagrama de classes do componente de Design Smells da ferramenta
SBSD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Figura 30 – Exemplo de representação do diagrama de classes na estrutura de árvore
de dependências. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Figura 31 – Pseudocódigo para identificar quais serviços foram impactados pelo
Global Processor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Figura 32 – Pseudocódigo para identificar quais leitores foram impactados pelo
Brain Reader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Figura 33 – Pseudocódigo para identificar quais processadores foram impactados
pelo Brain Processor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Figura 34 – Pseudocódigo para identificar quais escritores foram impactados pelo
Brain Writer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Figura 35 – Pseudocódigo para identificar quais componentes foram impactados
pelo Readaholic Component. . . . . . . . . . . . . . . . . . . . . . . . . 59
Figura 36 – Pseudocódigo para identificar quais componentes foram impactados
pelo Amateur Writer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Figura 37 – Pseudocódigo para identificar quais componentes foram impactados
pelo Improper Communication. . . . . . . . . . . . . . . . . . . . . . . 60
Figura 38 – Histograma da distribuição do total de linhas de código dos programas
utilizados no estudo de caso - Massa inicial. . . . . . . . . . . . . . . . 65
Figura 39 – Boxplot da distribuição do total de linhas de código dos programas
utilizados no estudo de caso - Massa inicial. . . . . . . . . . . . . . . . 66
Figura 40 – Histograma da distribuição do total de linhas de código dos programas
utilizados no estudo de caso - Massa filtrada. . . . . . . . . . . . . . . 67
Figura 41 – Boxplot da distribuição do total de linhas de código dos programas
utilizados no estudo de caso - Massa filtrada. . . . . . . . . . . . . . . 67
Figura 42 – Percentual de classes por papel arquitetural - Cálculo dos limites esta-
tísticos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Figura 43 – Percentual de classes por papel arquitetural - Estudo de caso. . . . . . 73
Figura 44 – Resultado estudo de caso - Fase 01 - Método 01. . . . . . . . . . . . . . 74
Figura 45 – Resultado estudo de caso - Fase 01 - Método 02. . . . . . . . . . . . . . 75
Figura 46 – Resultado estudo de caso - Fase 02 - Programa 01. . . . . . . . . . . . 78
Figura 47 – Resultado estudo de caso - Fase 02 - Programa 02. . . . . . . . . . . . 79
Lista de tabelas
Tabela 1 – Métricas de software utilizadas para detecção dos Design Smells. . . . 51
Tabela 2 – Conjunto de classes e interfaces associadas aos papeis arquiteturais das
aplicações batches. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Tabela 3 – Lista de operadores da linguagem SQL utilizados no cálculo da métrica
SQLComplexity. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Tabela 4 – Visão geral dos sistemas selecionados para validação da ferramenta SBSD. 60
Tabela 5 – Resultado da análise manual de Design Smells. . . . . . . . . . . . . . 61
Tabela 6 – Resultado da análise automática de Design Smells. . . . . . . . . . . . 61
Tabela 7 – Comparação dos resultados das análises manual e automática de Design
Smells. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Tabela 8 – Número de ocorrências de falsos positivos e falsos negativos. . . . . . . 62
Tabela 9 – Cálculo das métricas Precision, Recall e F-measure. . . . . . . . . . . . 63
Tabela 10 – Massa de dados inicial para o estudo de caso. . . . . . . . . . . . . . . 64
Tabela 11 – Resumo estatístico do total de linhas de código dos programas utilizados
no estudo de caso - Massa inicial. . . . . . . . . . . . . . . . . . . . . . 65
Tabela 12 – Massa de dados filtrada para o estudo de caso. . . . . . . . . . . . . . 66
Tabela 13 – Resumo estatístico do total de linhas de código dos programas utilizados
no estudo de caso - Massa filtrada. . . . . . . . . . . . . . . . . . . . . 66
Tabela 14 – Bases de dados finais para o cálculo de limites estatísticos e execução
do estudo de caso. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Tabela 15 – Bases de dados de papéis arquiteturais para cálculo de limites estatísticos. 68
Tabela 16 – Limites estatísticos calculados pelo método de análise de percentis. . . 70
Tabela 17 – Limites estatísticos calculados pelo método de análise de variabilidade. 72
Tabela 18 – Base de dados para execução do estudo de caso. . . . . . . . . . . . . . 73
Tabela 19 – Programas utilizados na segunda fase do estudo de caso - Estudo do
comportamento dos smells. . . . . . . . . . . . . . . . . . . . . . . . . 73
Tabela 20 – Resultado do cálculo da métrica Smell Density para os programas
analisados no estudo de caso. . . . . . . . . . . . . . . . . . . . . . . . 76
Lista de abreviaturas e siglas
AST Abstract Syntax Tree
COBOL Common Object Business Model
DATAPREV Empresa de Tecnologia e Informações da Previdência
FICP Fan-IN Class Processor
FIMP Fan-IN Method Processor
INSS Instituto Nacional de Seguridade Social
JCP Java Community Process
JSR Java Specification Reference
LCOM Lack Of Cohesion
LOC Lines Of Code
MVC Model-View-Controller
MTV Model-Template-View
SBSD Spring Batch Smell Detector
SQL Structured Query Language
UML Unified Modeling Language
WMC Weighted Method Count
Sumário
1 INTRODUÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.1 Contexto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.2 Problema de Pesquisa . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.3 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.4 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.5 Estrutura do Documento . . . . . . . . . . . . . . . . . . . . . . . . . 17
2 REFERENCIAL TEÓRICO . . . . . . . . . . . . . . . . . . . . . . . 18
2.1 Aplicações de processamento em lotes . . . . . . . . . . . . . . . . . 18
2.2 Spring Batch framework . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.3 Especificação JSR-352 . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.4 Arquitetura de referência . . . . . . . . . . . . . . . . . . . . . . . . .20
2.4.1 Execução do processamento em lotes . . . . . . . . . . . . . . . . . . . . 22
2.5 Design Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.6 Detecção de Design Smells . . . . . . . . . . . . . . . . . . . . . . . . 24
3 TRABALHOS RELACIONADOS . . . . . . . . . . . . . . . . . . . . 25
3.1 Design Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2 Detecção de Design Smells . . . . . . . . . . . . . . . . . . . . . . . . 26
4 DESIGN SMELLS EM APLICAÇÕES COM SPRING BATCH FRA-
MEWORK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.1 Catálogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.1.1 Global Processor (Classe de Processamento Global) . . . . . . . . . . . . . 30
4.1.2 Brain Reader (Leitor Complexo) . . . . . . . . . . . . . . . . . . . . . . . 33
4.1.3 Brain Processor (Processador Complexo) . . . . . . . . . . . . . . . . . . 35
4.1.4 Brain Writer (Escritor Complexo) . . . . . . . . . . . . . . . . . . . . . . 37
4.1.5 Readaholic Component (Leitor Compulsivo) . . . . . . . . . . . . . . . . . 39
4.1.6 Amateur Writer (Escritor Amador) . . . . . . . . . . . . . . . . . . . . . . 41
4.1.7 Improper Communication (Comunicação Indevida) . . . . . . . . . . . . . 44
5 FERRAMENTA DE DETECÇÃO . . . . . . . . . . . . . . . . . . . . 47
5.1 Levantamento do Estado da Prática . . . . . . . . . . . . . . . . . . . 47
5.2 Visão Arquitetural . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.3 Implementação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.3.1 Módulo de Métricas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.3.1.1 Métrica ArchitectureRole . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.3.1.2 Métrica ReferencedClasses . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.3.1.3 Métrica ReferencedMethods . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.3.1.4 Métrica SQLComplexity . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.3.2 Módulo de Dependências . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
5.3.3 Módulo de Design Smells . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.3.3.1 Global Processor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.3.3.2 Brain Reader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.3.3.3 Brain Processor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.3.3.4 Brain Writer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.3.3.5 Readaholic Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.3.3.6 Amateur Writer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5.3.3.7 Improper Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.4 Validação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.4.1 Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6 ESTUDO DE CASO . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
6.1 Preparação da Base de Dados . . . . . . . . . . . . . . . . . . . . . . 64
6.2 Cálculo dos Limites Estatísticos . . . . . . . . . . . . . . . . . . . . . 68
6.3 Execução da Ferramenta . . . . . . . . . . . . . . . . . . . . . . . . . 72
6.4 Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.4.1 Primeira Fase (RQ1, RQ2 e RQ3) . . . . . . . . . . . . . . . . . . . . . . 74
6.4.2 Segunda Fase (RQ4 e RQ5) . . . . . . . . . . . . . . . . . . . . . . . . . 77
7 CONSIDERAÇÕES FINAIS . . . . . . . . . . . . . . . . . . . . . . . 81
7.1 Generalização do Catálogo de Design Smells . . . . . . . . . . . . . . 81
7.2 Principais Contribuições . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.3 Ameaças à Validade . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.3.1 Ameaças à validade do estudo . . . . . . . . . . . . . . . . . . . . . . . . 82
7.3.2 Ameaças à validade da ferramenta . . . . . . . . . . . . . . . . . . . . . . 83
7.4 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
REFERÊNCIAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
12
1 Introdução
Controlar o processo de manutenção e evolução do software é de extrema importân-
cia para definir o grau de qualidade e longevidade de um sistema. Trata-se de uma tarefa
complexa em que os problemas são latentes devido à natureza da evolução continua que um
software possui. Muitos fatores impactam na qualidade desse processo, tais como: tamanho
do código fonte, complexidade, frequência de modificações, documentação, experiência e
estabilidade da equipe de desenvolvimento (ALKHARABSHEH et al., 2019). Questões
como inexperiência, falta de conhecimento e pressões em relação ao tempo de conclusão
de tarefas levam a adoção de más práticas de design, que são a origem dos Design Smells
(GARCíA, 2011). Design Smells não produzem erros de compilação ou execução, mas
afetam negativamente importantes atributos de qualidade, como compreensibilidade, tes-
tabilidade, extensibilidade, reusabilidade e a manutenibilidade (ALKHARABSHEH et al.,
2019). São visualizados como pistas de que algo pode estar errado na estrutura do sistema,
servindo de alertas, oportunidades de refatoração (BAVOTA et al., 2015) ou indicativos
de um aumento da dívida técnica dos projetos (ALKHARABSHEH et al., 2019).
A presença de Design Smells pode sinalizar possíveis pontos de degradação. De
acordo com Martin (2002), os Design Smells penetram em toda a estrutura do software, e
podem ser encontrados quando os sistemas apresentam sintomas de rigidez, fragilidade,
imobilidade, viscosidade, complexidade desnecessária, repetição ou opacidade.
Devido a essa natureza pervasiva e ao grande número de projetos de software que
possuem grandes dimensões, a detecção manual de Design Smells pode se tornar uma
tarefa não realista (ALKHARABSHEH et al., 2019). Por esses motivos, muitos estudos
estão sugerindo variadas técnicas para automatizar a detecção, sendo uma grande parte
baseada em métricas de software. Em 2018, Khalid Alkharabsheh realizou uma revisão
sistemática de 395 artigos publicados num período de 17 anos referentes à técnicas de
detecção de Design Smells (ALKHARABSHEH et al., 2019). A revisão constatou que 34%
dos estudos propuseram abordagens baseadas na medição de métricas de software, como
coesão, herança, dependência e acoplamento.
Mas apenas extrair métricas dos componentes de software não nos dá uma ideia do
contexto geral da aplicação. É necessário ter uma referência para entender se os valores
extraídos para uma determinada métrica representam realmente um problema. Para isso,
é preciso entender a distribuição das métricas ao longo do sistema e conhecer os fatores
que as influenciam. O trabalho de Dósea, Sant’Anna e Silva (2018) verificou que decisões
de design podem influenciar na distribuição das métricas, evidenciando a importância de
se considerar fatores como o tipo de aplicação, arquitetura utilizada e o papel arquitetural
Capítulo 1. Introdução 13
de cada componente analisado. Além de influenciar a distribuição dos valores, cada tipo de
aplicação que utiliza determinada arquitetura pode sofrer problemas específicos e apresentar
novos tipos de Design Smells ainda não documentados. Outros trabalhos estão aplicando
essa abordagem e definindo Design Smells específicos para arquiteturas analisadas, como os
trabalhos de Aniche et al. (2018), Correia e Adachi (2019), Carvalho et al. (2019) e Laigner
et al. (2019), que definem respectivamente smells específicos para as arquiteturas MVC -
Model-View-Controller, MTV - Model-Template-View, Aplicações Android e injeção de
dependência em aplicações Java.
Desta forma, a definição e identificação de smells específicos para uma determinada
arquitetura, aparenta ser uma estratégia efetiva para mitigar problemas relacionados ao
contexto específico da aplicação, e por consequência, minimizara degradação arquitetural
causada pelas sucessivas ações de atualização e manutenção que o software recebe ao longo
de seu tempo de vida.
1.1 Contexto
O contexto de estudo desse trabalho é o projeto de migração tecnológica realizado
pela DATAPREV, empresa pública que fornece soluções de tecnologia da informação e
comunicação para programas de políticas sociais do Estado brasileiro. O projeto “Migração
CV3” corresponde a migração de sistemas desenvolvidos em tecnologias legadas para
tecnologias mais contemporâneas, e compreende sistemas críticos da empresa, responsáveis
principalmente pelo processamento de toda folha de pagamento previdenciária do INSS -
Instituto Nacional de Seguridade Social, algo por volta de mais de 54 milhões de registros
de benefícios por mês.
Os programas foram originalmente desenvolvidos na linguagem de programação
COBOL -Commom Object Business Model, para serem executados em Mainframes compa-
tíveis com essa tecnologia. Essa arquitetura impôs a empresa uma dependência tecnológica
de hardware e mão de obra especializada, pois os Mainframes utilizados contam com
apenas um fornecedor e a cada dia a disponibilidade de profissionais especializados na
linguagem legada vem decaindo. Grande parte desses programas utilizam o modelo de
processamento de informações em lotes e são executados de forma automatizada com o
mínimo de intervenção humana. A figura 1 apresenta o diagrama do projeto de migração
dos programas legados.
Capítulo 1. Introdução 14
Figura 1 – Etapas do processo de migração tecnológica do CV3.
Conforme explícito na figura 1, o projeto de migração utilizou uma estratégia de
tradução automatizada de código, onde o código legado COBOL foi automaticamente
traduzido para código Java utilizando uma ferramenta proprietária de mercado. O resultado
de cada tradução foi um programa equivalente escrito na linguagem de programação Java,
utilizando o framework de desenvolvimento de programas de processamento em lotes
Spring Batch. Após a fase de tradução, foi necessária a realização de ajustes e otimizações
no código traduzido, para equiparar os resultados entre as execuções dos programas
Cobol e Java, eliminando os defeitos funcionais provenientes do processo de tradução,
e melhorar o desempenho das novas aplicações, aplicando refatorações com foco na
otimização da execução dos programas. Essa fase de otimização já era esperada devido à
natureza da linguagem legada, que utiliza paradigma de desenvolvimento procedural, com
programas muitas vezes escritos em grandes blocos de código de um único arquivo, que
foram idealizados para serem executados em um hardware específico, não considerando
critérios de desempenho necessários para execução em equipamentos mais modernos. Essas
características da linguagem legada resultavam na tradução de programas Java com classes
muito extensas, complexas e com uma quantidade exagerada de acessos a repositórios de
dados, que degradavam o desempenho das aplicações.
Nessa última fase de otimização, os desenvolvedores tinham a missão de alterar os
programas visando a eliminação de defeitos funcionais e melhorar a qualidade do código
migrado com base em critérios de manutenibilidade e desempenho. Porém, não existiam
referências de como realizar essa otimização, ou de indicadores de problemas específicos
do contexto da programação em lotes. Por esse motivo, a maioria das refatorações foram
aplicadas apenas para correção dos defeitos funcionais, desconsiderando particularidades
Capítulo 1. Introdução 15
da arquitetura de processamento em lotes que poderiam elevar ainda mais o grau de
qualidade dos programas migrados.
Portanto, para auxiliar a equipe de desenvolvimento na fase de otimização do
projeto, seria interessante a elaboração de uma documentação de referência que defina
os impactos, indicadores e técnicas para localização de possíveis problemas relacionados
ao contexto das aplicações de processamento em lotes, bem como, a criação de uma
ferramenta de análise automatizada para auxiliar na identificação dos pontos onde ocorrem.
A ausência de uma documentação de referência e um apoio ferramental pode impedir que
se obtenha resultados ainda mais favoráveis nas tarefas de otimização dos sistemas, que
sem um processo de refatoração considerando particularidades do contexto das aplicações,
dificulta a busca e análise de pontos de melhoria no código das aplicações. Não saber
quando determinado componente se mostra muito complexo, de acordo com o papel
arquitetural que desempenha, ou está impondo uma complexidade desnecessária aos
demais componentes ao qual se relaciona, impede que melhorias sejam aplicadas para
diminuir a complexidade do processamento e aumentar o grau de manutenibilidade geral da
aplicação. O mesmo ocorre quando não se conhece os fatores que podem estar degradando
o desempenho da execução, resultando em buscas mais amplas, custosas, e por vezes sem
resultados, para identificação desses pontos de degradação.
1.2 Problema de Pesquisa
Aplicações de processamento em lotes, ou aplicações batches, tem sua origem
atrelada a própria história da computação. As primeiras aplicações surgiram na década de
50 com o surgimento dos transistores, que deram origem aos computadores de grande porte.
São caracterizadas pela manipulação de um grande volume de dados ou de um extensivo
e longo processamento computacional. Geralmente são executadas em segundo plano e
não necessitam de interação com usuários (VIGNOLA, 2013). Apesar de possuírem uma
longa história, as aplicações batches ainda são relevante no contexto da computação atual.
Transações bancárias, serviços de envio de e-mails, geração de modelos de recomendação
para grandes corporações e orquestração de tarefas em sistemas de Big Data são exemplos
de operações executadas através de processamento em lotes (MINELLA, 2019).
Como em qualquer outro tipo de arquitetura, os sistemas de processamento em
lotes necessitam evitar a degradação estrutural e se manterem no projeto arquitetural
pretendido, por esses motivos, é importante conhecer as regras da arquitetura utilizada e
saber identificar onde ocorrem violações. A definição de um catálogo de Design Smells,
específicos para contexto de aplicações batches, pode ser um grande aliado para garantir a
manutenção da arquitetura pretendida. Definir Design Smells específicos ajuda a expor
possíveis problemas que só existem no contexto de processamento em lotes, e uma vez
Capítulo 1. Introdução 16
conscientes desses problemas, as equipes de desenvolvimento podem atuar e garantir um
nível mais elevado de qualidade para as aplicações, evitando a degradação da estrutura
proposta para o sistema.
Outros tipos de arquitetura já possuem trabalhos semelhantes nos quais propõem
a definição de Design Smells específicos, como as arquiteturas MVC (ANICHE et al.,
2018), MTV (CORREIA; ADACHI, 2019), aplicações Android (CARVALHO et al., 2019)
e injeção de dependência (LAIGNER et al., 2019) em programas Java. Porém, não foram
encontrados estudos referentes a definição ou análise de Design Smells específicos para
aplicações de processamento em lotes, sendo o principal problema de pesquisa a ser
resolvido por essa dissertação. Além disso, é importante garantir a aplicabilidade da análise
dos Design Smells que serão definidos, pois devido ao aumento constante das dimensões
de tamanho e complexidade das aplicações desenvolvidas atualmente, a detecção manual
pode não ser uma tarefa realista, o que torna a implementação de uma ferramenta de
detecção automatizada de Design Smells específicos para aplicações batches o segundo
problema de pesquisa a ser resolvido pela dissertação.
1.3 Objetivo
O objetivo geral deste trabalho é:
Definir e apoiar a detecção de Design Smells específicos à arquitetura de sistemas
de processamento em lotes.
São objetivos específicos deste trabalho:
• Elaboração de um catálogo de Design Smells para problemas específicos da arquite-
tura de referência.
• Implementação de ferramenta de apoio na identificação dos Design Smells definidosno catálogo elaborado.
1.4 Metodologia
A metodologia para execução deste trabalho utilizou os seguintes procedimentos:
• Revisão da literatura: Com o objetivo de identificar trabalhos relacionados ao
estudo de smells referentes ao contexto das aplicações de processamento em lotes,
elaborar a definição de estratégias de detecção de violações arquiteturais e a identificar
smells tradicionais que possam se adequar ao contexto estudado, foi realizada uma
revisão de literatura para servir de base para a construção do catálogo de Design
Smells.
Capítulo 1. Introdução 17
• Elaboração do catálogo de Design Smells: As violações identificadas referentes
ao contexto das aplicações de processamento em lotes foram documentadas por meio
de um catálogo de Design Smells. O catálogo apresenta a definição de cada violação,
expõe os impactos gerados, define estratégias de detecção e apresenta propostas para
refatoração.
• Implementação de ferramenta para identificação de Design Smells: Para
auxiliar o processo de identificação dos Design Smells, foi desenvolvida uma ferra-
menta para análise do código fonte que utiliza as estratégias de detecção definidas
no catálogo do item anterior.
• Avaliação da ferramenta de identificação de Design Smells: Para validar a
utilização da ferramenta de identificação, foi realizado um processo de avaliação,
onde foram comparados os resultados da identificação dos Design Smells realizados
pela ferramenta, contra os resultados do processo de identificação manual realizado
pelo autor dessa dissertação. Foram avaliados critérios de precisão e relevância dos
resultados encontrados.
• Estudo de caso: Para verificar a aplicabilidade do catálogo proposto, a ferramenta
de identificação foi aplicada em um estudo de caso com os programas que participaram
do projeto de migração tecnológica da DATAPREV. Esse estudo buscou, além da
validação das estratégias de detecção, identificar padrões de comportamento dos
Design Smells ao longo do tempo do projeto.
1.5 Estrutura do Documento
As seções seguintes desse documento estão estruturadas da seguinte forma: Ca-
pítulo 2 - Referencial teórico, contém as principais definições para o entendimento dos
assuntos discutidos. Capítulo 3 - Trabalhos relacionados, apresenta os trabalhos publicados
relacionados ao tema. Capítulo 4 - Definição do catálogo de Design Smells para aplicações
utilizando o Spring Batch framework. Capítulo 5 - Implementação da ferramenta de
detecção dos Design Smells definidos no catálogo do capítulo 3. Capítulo 6 - Estudo de
caso realizado com os programas da migração tecnológica. Capítulo 7 - Considerações
finais, contendo as considerações finais para trabalho, as principais contribuições e as
propostas de trabalhos futuros.
18
2 Referencial Teórico
Essa seção tem por objetivo apresentar um referencial teórico para os principais
conceitos utilizados no estudo dessa dissertação. Serão apresentados: a definição de uma
aplicação de processamento em lotes ou aplicação batch, seu histórico e evolução; o
framework Spring Batch, desenvolvido para construção de aplicações de processamento
em lotes; a especificação JSR-352, que define um modelo de programação para aplicações
batches na linguagem de programação JAVA; a arquitetura de referência utilizada pelo
framework Spring Batch e a especificação JSR-352 ; e a definição de Design Smells.
2.1 Aplicações de processamento em lotes
O conceito de aplicações de processamento em lotes tem origem atrelada a pró-
pria história da computação. As primeiras aplicações surgiram na década de 50 com o
surgimento dos transistores, que deram origem aos computadores de grande porte. Essas
máquinas possuíam altos custos e apenas grandes corporações, agências do governo e
universidades dispunham de recursos para aquisição. Devido ao alto valor do equipamento
foi necessário buscar uma forma de otimizar o uso, evitando períodos de ociosidade,
ocasionados principalmente pela necessidade de intervenção dos usuários para troca de
programas a cada execução de uma nova tarefa. A solução adotada foi reunir um lote de
tarefas para que fossem processadas sequencialmente. A cada ciclo, um conjunto de tarefas
era lido, executado e gravado sem a necessidade de interação com usuários, reduzindo o
tempo ocioso de máquina (TANENBAUM; BOS, 2016).
Aplicações de processamento em lotes, ou aplicações batches, são caracterizadas
pela manipulação de um grande volume de dados ou de um extensivo e longo processamento
computacional. Geralmente são executadas em segundo plano e não necessitam de interação
com usuários (VIGNOLA, 2013). Atualmente, muitas aplicações corporativas utilizam
esse conceito para concretizar operações críticas de negócio, como exemplos: processos
complexos que atuam em grandes volumes de dados e são executados de forma mais eficiente
sem a interação de usuários; aplicações periódicas de regras de negócio em grandes massas
de dados; ou integração de sistemas distintos que necessitam realizar pré-processamentos
nas informações trocadas (WARD DAVE SYER; HASSINE, 2019). A figura 2 ilustra um
exemplo comum do uso das aplicações de processamento em lotes.
Capítulo 2. Referencial Teórico 19
Figura 2 – Exemplo básico de uma aplicação de processamento em lotes.
A figura 2 mostra um exemplo básico de uma aplicação de processamento em lotes
na integração de sistemas. Os dados do sistema A são extraídos, processados e armazenados
em lotes no sistema B sem a necessidade de interação com o usuário.
Apesar de importantes e muito utilizadas, é perceptível ao longo dos anos uma
falta de foco na criação de uma arquitetura padrão e reutilizável voltada às aplicações
batches, tanto em programas legados quanto em aplicações desenvolvidas em linguagens
mais contemporâneas como Java. Como consequência, ocorreu uma proliferação de soluções
personalizadas desenvolvidas para atender as necessidades de cada instituição (WARD
DAVE SYER; HASSINE, 2019). No intuito de contornar esse cenário, alguns projetos de
definição de arquiteturas padronizadas e criação de frameworks foram criados para auxilio
ao desenvolvimento. As próximas seções descrevem com mais detalhes esses projetos e
apresentam a arquitetura de referência adotada por eles.
2.2 Spring Batch framework
O Spring Batch é resultado de uma parceria entre as empresas Pivotal (empresa
responsável pelo framework Spring) e a Accenture (empresa multinacional de desenvol-
vimento de software) para construção de um framework com o objetivo de promover a
padronização de abordagens, estruturas e ferramentas de processamento de software que
possam ser constantemente aproveitadas pelos usuários corporativos ao criar programas de
processamento em lotes. O Spring Batch descreve uma arquitetura de referência elencando
papeis e responsabilidades, define uma linguagem de domínio comum para aplicações bat-
ches e disponibiliza funcionalidades para atendimento a requisitos não funcionais comuns,
como log, backup e processamento paralelo (WARD DAVE SYER; HASSINE, 2019).
Capítulo 2. Referencial Teórico 20
2.3 Especificação JSR-352
A JSR-352 é uma requisição de especificação para linguagem JAVA elaborada
pelo Java Community Process (JCP), a qual propõe um modelo de programação para
aplicações de processamento em lotes. Essa especificação utiliza a mesma arquitetura de
referência e linguagem de domínio definidas pelo framework Spring Batch e adicionalmente
propõe uma linguagem para configuração do processamento em lotes no formato XML
(VIGNOLA, 2013).
2.4 Arquitetura de referência
Durante a iniciativa do projeto Spring Batch, a Accenture contribuiu com a de-
finição de uma arquitetura padrão de estruturas comumente utilizadas em projetos de
processamento em lotes, desenvolvidos pela empresa ao longo de décadas de experiência
com variadas gerações de plataformas, COBOL/Mainframe, C++/Unix e Java.
A figura 3, retirada da documentação oficial do framework Spring Batch (WARD
DAVE SYER; HASSINE, 2019), exibe os principais componentes da arquitetura de
referência e seus relacionamentos.Figura 3 – Arquitetura de referência para aplicações de processamento em lotes.
O principal elemento da arquitetura é o Job, que serve de contêiner para toda
configuração da aplicação batch. O Job é responsável por agrupar as etapas do processo,
organizar o fluxo de execução, configurar parâmetros globais e definir se o processo pode
ser reinicializado em caso de falhas.
O Step é um objeto de domínio que representa uma fase independente do processa-
mento. Um Job é composto por um ou mais Steps que são agrupados e organizados de
acordo com o fluxo de execução do processo em lotes. Dentro do Step são configuradas as
Capítulo 2. Referencial Teórico 21
ações do processo, que geralmente compreendem a leitura de uma fonte de dados, seguida
pelo processamento das informações e finalizando com a escrita do conteúdo processado
em um repositório de dados.
O Item Reader é uma abstração que representa o procedimento de leitura de dados
de um Step. O papel representado por esse componente é ler de uma fonte de dados
e repassar as informações para o componente de processamento. Esse leitor não está
interessado como os dados serão manipulados, outro componente da arquitetura será
responsável por transformar esses dados em um formato legível ao processamento da
aplicação.
Apesar de não estarem explícitos no diagrama da figura 3, osMappers desempenham
um papel importante na arquitetura. São eles que transformam as informações extraídas
pelos leitores em objetos de domínio que são compreendidos pelo processamento da
aplicação.
O componente Item Processor é responsável pelo processamento das informações,
nesse ponto as regras de negócio devem ser aplicadas. O Item Processor recebe os dados do
Item Reader , já convertidos em objetos de domínio pelo Mapper , e os processa um a um.
Ao final de cada iteração, é gerado um objeto que será repassado para o armazenamento
em um repositório de dados.
O Item Writer possui função contrária ao Item Reader . Esse componente é respon-
sável pela escrita das informações processadas em um repositório de dados. Diferente do
Item Processor , que trabalha com um item por vez, esse escritor trabalha com uma lista
de itens que são armazenados a cada ponto de checagem do processamento em lotes. O
tamanho dessa lista vai variar de acordo com parâmetro configurado no Step.
Para manter as informações de controle de um Job, a arquitetura de referência
especifica um banco de metadados chamado Job Repository. Nele são armazenadas infor-
mações de execução, como exemplo: data das últimas execuções; situação da execução
atual; resultado dos últimos processamentos; número de registros lidos, processados e
gravados. Durante toda execução os componentes da arquitetura devem se comunicar
com o repositório para armazenar a situação atual do processamento. É através desse
mecanismo que a arquitetura permite que um processamento em lotes seja reinicializado
do ponto onde parou em caso de falhas.
O componente Job Operator é responsável por prover uma interface de gerencia-
mento para o Job. Ele disponibiliza funcionalidades para iniciar, pausar ou cancelar uma
execução e também métodos de acesso e manipulação do repositório de metadados.
Capítulo 2. Referencial Teórico 22
2.4.1 Execução do processamento em lotes
A figura 4 exibe o diagrama de sequência UML de uma aplicação de processamento
batch utilizando a arquitetura de referência. Todo o procedimento inicia com a execução
do Job por meio do Job Operator . O Job irá executar os Steps na ordem em que foram
configurados. Cada Step enviará solicitações de leitura para seu respectivo Item Reader ,
que obterão as informações de uma fonte de dados e delegarão aos Mappers a conversão
para um formato legível para aplicação. Com os dados obtidos, o Step requisitará ao
Item Processor o processamento e aplicação de regras de negócio, para cada item por vez.
Após processado, cada item será armazenado em uma lista de itens processados, onde
aguardarão um ponto de checagem da aplicação para serem enviados de uma só vez ao
Item Writer , que realizará a escrita em um repositório de dados.
Figura 4 – Exemplo de diagrama de sequência UML da execução do processamento em
lotes utilizando a arquitetura de referência.
2.5 Design Smells
Fowler e Beck (1999) foram os primeiros a utilizar o termo Code Smells, definindo-o
como a ocorrência de certas estruturas no código que sugerem a possibilidade de aplicações
de refatorações. O foco dos Code Smells é o código fonte das aplicações, que incluem classes,
métodos ou blocos menores de instruções. A ideia principal é identificar estruturas de código
que indiquem determinados pontos da aplicação que estão sofrendo degradação de atributos
importantes de qualidade, como compreensibilidade, extensibilidade e manutenibilidade.
Para isso, eles apresentaram um catálogo com 22 tipos de Code Smells que podem identificar
a ocorrência desses problemas, indicando como pontos de verificação a presença de trechos
Capítulo 2. Referencial Teórico 23
de código repetidos, métodos e classes muito extensas, longa lista de parâmetros e outras
estruturas que podem ser vistas em (FOWLER; BECK, 1999).
Semelhante aos Code Smells mas com um escopo de atuação mais amplo, existem
os Architectural Smells. Que foram definidos por Garcia et al. (2009a) como decisões
arquiteturais comumente utilizadas que impactam negativamente a qualidade dos sistemas.
Os Architectural Smells não afetam apenas estruturas de mais alto nível, como pacotes e
subsistemas, mas também impactam na própria organização e modo de execução, pois
podem afetar a forma em que um sistema é organizado, como os componentes se relacionam
e como suas funcionalidades são distribuídas. Podem ser incorporados às aplicações ao
se utilizar soluções de design em contextos inapropriados, misturar diferentes soluções
arquiteturais que podem ser incompatíveis e resultar em comportamentos indesejáveis, ou
aplicar abstrações de design em níveis de granularidade equivocados, como uma solução
que deveria ser aplicada em uma hierarquia de classes ser aplicada a nível de subsistemas
(GARCIA et al., 2009a).
Os Code Smells possuem um escopo mais localizado, identificando problemas rela-
cionados a aspectos de código, diferente dos Architectural Smells, que possuem um escopo
mais amplo com foco em aspectos da arquitetura da aplicação. Já o termo Design Smells
definido por Martin (2002) e unificado por García (2011), possui um escopo mais amplo co-
brindo todas as estruturas do software, o que vai ao encontro do comportamento pervasivo
apresentado pelos Smells, que podem afetar desde de pequenas estruturas de código, como
variáveis e blocos de instruções, a artefatos arquiteturais, como pacotes e subsistemas.
Design Smells são problemas encontrados na estrutura do software (código ou design),
que não produzem erros de compilação ou execução, mas afetam negativamente fatores de
qualidade como a compreensibilidade, reusabilidade, testabilidade e a manutenibilidade em
geral (GARCíA, 2011). De acordo com Martin (2002), os Design Smells penetram em toda
a estrutura do software, e podem ser encontrados quando os sistemas apresentam sintomas
de rigidez, fragilidade, imobilidade, viscosidade, complexidade desnecessária, repetição e
opacidade. Apesar de estarem diretamente ligados a fatores negativos, os Design Smells
não representam diretamente um defeito, mas sua presença serve de alerta para possíveis
problemas na estrutura do software, podendo ser considerada o indicativo de uma estrutura
fraca de código que contribui para o aumento da dívida técnica (ALKHARABSHEH et al.,
2019), e consequentemente sinalizar oportunidades de refatoração do software (BAVOTA
et al., 2015). Este trabalho utilizará a definição de Design Smells conforme García (2011),
e considerará toda estrutura do software (código ou design) passível de análise.
Capítulo 2. Referencial Teórico 24
2.6 Detecção de Design Smells
Devido à natureza pervasiva dos Design Smells e ao grande número de projetos
de software que possuemgrandes dimensões, a detecção manual pode se tornar uma
tarefa não realista (ALKHARABSHEH et al., 2019), por esses motivos, muitos estudos
estão sugerindo variadas técnicas para automatizar a detecção. Alkharabsheh et al. (2019)
realizaram uma revisão sistemática com 395 artigos publicados num período de 17 anos
referentes à técnicas de detecção de Design Smells, e constataram a utilização de estratégias
baseadas em regras lógicas, aprendizado de máquina, grafos, análise de especialistas e
métricas de software. Uma grande parte dos trabalhos encontrados foram baseados em
métricas de software, a revisão constatou que 34% dos estudos propuseram abordagens
baseadas na medição de métricas como coesão, herança, dependência e acoplamento.
Porções do software que apresentassem métricas com valores destoantes de determinados
limites, definidos pelas técnicas utilizadas, eram apontados como possíveis focos de Design
Smells.
Utilizando essa abordagem, Lanza e Marinescu (2007) propuseram um conjunto de
estratégias de detecção baseadas na análise de métricas extraídas dos sistemas analisados.
Para cada métrica utilizada, uma análise estatística foi realizada, considerando todo o
software, para definir intervalos que seriam considerados valores médios, altos ou muito
altos. As estratégias de detecção se basearam nesses limites para identificar pontos que
apresentavam um conjunto de métricas com valores dissonantes do restante da aplicação.
Dada a utilização de métricas nas estratégias de detecção de Design Smells, o
trabalho de Dósea, Sant’Anna e Silva (2018) procurou verificar a influência das decisões
de design na distribuição de seus valores, e constatou que os papeis arquiteturais de-
sempenhados pelos componentes do software influenciam diretamente nessa distribuição,
evidenciando a importância de se considerar fatores como o tipo de aplicação, arquitetura
utilizada e o papel arquitetural de cada componente analisado. Seguindo essa linha de
raciocínio, outras técnicas para detectar Design Smells sensíveis ao contexto estudado
foram propostas, e levam em conta aspectos específicos das aplicações analisadas, como
padrão arquitetural escolhido, plataforma de execução ou framework utilizado.
25
3 Trabalhos Relacionados
Este capítulo apresenta os principais trabalhos relacionados à definição, estudo e
estratégia de detecção de Design Smells que serviram de base para criação do catálogo
proposto no capítulo 4.
3.1 Design Smells
Na literatura, diversos trabalhos definem os Design Smells por meio de diferentes
termos: Code Smells ou Bad Smells (FOWLER; BECK, 1999), Architectural Smells
(GARCIA et al., 2009b), antipadrões (BROWN et al., 1998), desarmonias (LANZA;
MARINESCU, 2007), falhas de design (SALEHIE; LI; TAHVILDARI, 2006), defeitos de
design (MOHA, 2007), anomalias de código (WASYLKOWSKI; ZELLER; LINDIG, 2007)
ou débitos de design (ZAZWORKA et al., 2011). Yamashita e Moonen (2013) constataram
que 27% dos problemas encontrados na manutenção do software estudado ocorreram
devido a presença de Code Smells.
Fowler e Beck (1999) foram os primeiros a utilizar o termo Code Smells, eles
apresentaram um catálogo com 22 Code Smells referentes a problemas genéricos de design
de código que poderiam afetar qualquer tipo de aplicação. Brown et al. (1998) apresentaram
uma nova nomenclatura para os smells, denominada Antipatterns ou antipadrões, eles
descreveram 41 antipadrões que não apenas abordaram o escopo de código, mas expandiram
a análise para a arquitetura do sistema e até o gerenciamento de projetos. Lanza e Marinescu
(2007) definiram um catálogo de Design Smells denominados de “desarmonias”, o trabalho
afirmava que cada artefato de software deveria estar em harmonia com ele mesmo (tamanho
e complexidade), em harmonia com outros artefatos que se relaciona (acoplamento), e
em harmonia com seus ancestrais e descendentes (herança). Também foram definidas
estratégias de detecção baseadas em análise de métricas de software, e sugestões de
refatoração para cada uma das desarmonias. Garcia et al. (2009a) introduziram o conceito
de Architectural Smells, demostrando o que possuíam de diferente dos Code Smells e dos
Antipatterns, também descreveram a definição de 4 Architectural Smells extraídos por
meio da análise de engenharia reversa de 18 projetos de software. Macia et al. (2012)
reportaram uma relação entre problemas arquiteturais e a presença de smells, e Fontana et
al. (2019) realizaram um estudo para determinar se existia uma correlação entre a presença
de Code Smells e Architectural Smells, utilizaram 111 projetos de software para a análise
entre 4 tipos de Architectural Smells e 19 tipos de Code Smells, e constataram que não
existia correlação significativa entre os dois tipos de smells, direcionando a conclusão que
a presença de Code Smells não depende e não está relacionada a presença de Architectural
Capítulo 3. Trabalhos Relacionados 26
Smells. Moha (2007) propôs um framework para especificar, detectar e visualizar os Design
Smells, também desenvolveu uma linguagem de domínio específico que permite aos usuários
a especificação de novos smells (MOHA et al., 2008). E Sobrinho, Lucia e Maia (2018)
elaboraram uma revisão de literatura sobre Bad Smells de trabalhos publicados entre os
anos de 1990 e 2017, a revisão buscou analisar de forma ampla o ambiente de pesquisa
sobre Bad Smells, identificando quais os tipos presentes na literatura, como o interesse
sobre o tema tem se comportado com o tempo, os principais objetivos buscados pelas
pesquisas, quem são os principais pesquisadores do tema e onde são realizadas as principais
pesquisas sobre o assunto.
3.2 Detecção de Design Smells
Muitos estudos estão sugerindo variadas técnicas para automatizar a detecção de
Design Smells. Alkharabsheh et al. (2019) realizaram uma revisão sistemática com 395
artigos publicados num período de 17 anos referentes à técnicas de detecção de Design
Smells, e constataram a utilização de estratégias baseadas em regras lógicas, aprendizado
de máquina, grafos, análise de especialistas e métricas de software. Uma grande parte
dos trabalhos encontrados foram baseados em métricas de software. Lanza e Marinescu
(2007) propuseram um conjunto de estratégias de detecção baseadas na análise de métricas
extraídas dos sistemas analisados. E construíram um catálogo de “desarmonias” que
identificavam pontos com valores de métricas dissonantes do restante da aplicação.
Azadi, Fontana e Taibi (2019) catalogaram 11 Architectural Smells que possuíam
estratégias de detecção bem definidas e ferramentas automatizadas de detecção. O catálogo
trouxe uma definição de cada Architectural Smell, as variações de nomenclatura que os
smells possuíam, os princípios arquiteturais violados, as ferramentas de detecção existentes
e as estratégias utilizadas por cada ferramenta.
Dada a utilização de métricas nas estratégias de detecção de Design Smells, o
trabalho de Dósea, Sant’Anna e Silva (2018) constatou que os papeis arquiteturais de-
sempenhados pelos componentes do software influenciam diretamente na distribuição das
métricas, evidenciando a importância de se considerar fatores do contexto da aplicação na
análise. Seguindo essa linha de raciocínio, alguns trabalhos procuraram definir e detectar
Design Smells sensíveis ao contexto estudado.
Aniche et al. (2018) definiram 6 smells específicos para aplicações de internet que
utilizam o padrão arquitetural MVC e a linguagem de programação Java. A definição se
deu por meio de pesquisas e entrevistas com 53 desenvolvedores que utilizavam o padrão
há pelo menos um ano. Os smells foram validados utilizando diferentes perspectivas, como
a relação com a propensão a alterações e surgimento de falhas, o ciclo de vida de cada
Smell, a perspectiva de diferentes desenvolvedores sobre o catálogo e a possibilidade de
Capítulo 3. Trabalhos Relacionados 27
generalização para outras linguagens de programação. E constataram que a ocorrência
dos smells aumenta as chances de necessidade de alterações e correçõesdos sistemas, que
geralmente surgem com a criação dos arquivos e possuem um longo tempo de vida, são
percebidos como problemas severos nas aplicações e que o catálogo proposto possui a
capacidade de ser aplicado em outras linguagens de programação que utilizem o mesmo
padrão arquitetural.
Correia e Adachi (2019) se basearam no trabalho de Aniche et al. (2018) para
definir um catálogo de 5 Code Smells para aplicações Web utilizando o padrão MTV do
framework Django e a linguagem de programação Python. Eles também implementaram
uma ferramenta para automatizar a análise e detecção dos smells propostos, e realizaram
um estudo de caso em um sistema com mais de 175 mil linhas de código utilizado por mais
de 30 instituições de ensino brasileiras. O estudo concluiu que mais de 50% das violações
de design encontradas eram ocasionadas por apenas um dos Smell definidos, e semelhante
ao trabalho de Aniche et al. (2018), constataram que o número de violações se mantém
constante ao longo do ciclo de vida das aplicações.
Carvalho et al. (2019) realizaram um estudo envolvendo 246 desenvolvedores para
definir um catálogo de smells referentes a violações que afetam a camada de apresentação
de aplicações para dispositivos móveis utilizando a plataforma Android. Eles utilizaram
um questionário com 25 questões para obter informações dos desenvolvedores sobre os
principais problemas encontrados na implementação dessa camada. Com os resultados
obtidos foram definidos 20 smells, que foram avaliados pelos desenvolvedores em relação
a frequência e importância. Também foi desenvolvida uma ferramenta para automatizar
o processo de análise e detecção, que foi aplicada em um estudo de caso envolvendo 619
aplicações que utilizam a plataforma Android. Ao final do estudo, os resultados sugeriram
que os desenvolvedores estão cientes da existência de smells específicos à camada de
apresentação das aplicações móveis, que os mesmos desenvolvedores consideram que smells
propostos possuem grande importância e aparecem com frequência nas aplicações Android,
e que as violações realmente acontecem em programas no mundo real, não sendo apenas
problemas teóricos.
Apesar da importância e ampla utilização das aplicações batches, não foram en-
contrados trabalhos referentes a definição ou detecção de Design Smells específicos a esse
contexto.
28
4 Design Smells em Aplicações com Spring
Batch Framework
Este capítulo apresenta um catálogo de Smells aplicado a arquitetura de programas
de processamento em lotes utilizando o Spring Batch Framework. Todos os Smells propostos
foram idealizados considerando o contexto das aplicações de processamento em lotes e a
especificação JSR-352.
4.1 Catálogo
A ideia da produção de um catálogo com problemas que afetam especificamente
softwares de processamento em lotes surgiu da participação do autor dessa dissertação no
projeto de migração tecnológica CV3. O projeto utilizou a estratégia de tradução automa-
tizada de código para converter programas legados COBOL em programas modernizados
Java por meio de uma ferramenta proprietária de mercado. Após a tradução, uma fase de
otimização foi necessária para melhoria do código e correção de defeitos funcionais. Nessa
fase, as melhorias que não eram relacionadas a correção de defeitos funcionais tinham o
objetivo de melhorar atributos de qualidade com foco apenas em princípios e boas práticas
relacionadas a orientação a objetos, como herança, encapsulamento, coesão e acoplamento,
sem uma visão relacionada a arquitetura utilizada para processamento em lotes. Como
resultado, mesmo com as refatorações realizadas, o processo de manutenção ainda relatava
dificuldades referentes a complexidade, e o desempenho das aplicações não alcançava um
resultado satisfatório.
De face a esse cenário, verificou-se a necessidade de buscar estudos e documentações
de referência sobre boas práticas e resoluções de problemas relacionados ao contexto das
aplicações de processamento em lotes. O objetivo dessa pesquisa foi encontrar problemas que
frequentemente afetam esses tipos de aplicações e quais foram as soluções propostas. Porém,
não foram encontrados trabalhos com foco na melhoria do processo de desenvolvimento ou
algum catálogo com problemas específicos ao contexto das aplicações batches. Por esse
motivo, surgiu a necessidade de elaborar uma documentação que pudesse orientar o processo
de migração e manutenção na melhoria do código visando as características da arquitetura
utilizada. Para confecção dessa documentação, foi realizado um estudo aprofundado da
arquitetura de referência para tentar identificar estruturas que representassem violações
dos princípios de design definidos na especificação JSR-352. E baseado no trabalho de
Lanza e Marinescu (2007), buscou-se encontrar possíveis formas de desarmonias entre os
componentes da arquitetura de referência, bem como, a definição de estratégias de detecção,
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 29
utilizando métricas retiradas das aplicações analisadas, e sugestões de refatoração para
cada violação encontrada. O resultado final foi a elaboração de um catálogo com problemas
comuns que podem ser encontrados no desenvolvimento de aplicações de processamento em
lotes, utilizando a arquitetura referenciada nessa dissertação. O catálogo gerado procurou
possuir um aspecto prático, voltado principalmente a questões que realmente impactam o
processo de desenvolvimento e manutenção, e não apenas definir os Smells propostos, mas
também apresentar estratégias para detecção e refatoração dos problemas apresentados.
O catálogo apresentado nesse documento foi baseado no trabalho de Fowler e Beck
(1999), que propõe uma lista de indicadores de potenciais problemas de codificação, deno-
minados de Bad Smells, para aplicação ao contexto das aplicações de processamento em
lotes (Global Processor , Brain Reader , Brain Processor e Brain Writer). Também foram
sugeridos novos Smells referentes a problemas específicos na utilização da arquitetura de
aplicações batches (Readaholic Component, Amateur Writer e Improper Communication).
Para cada definição de Smell, foram definidas estratégias de detecção e de refatoração,
semelhantes as definidas no trabalho de Lanza e Marinescu (2007), ao qual propõe estraté-
gias de detecção e técnicas de refatoração para desarmonias entre os componentes de uma
aplicação. O catálogo pode ser dividido de acordo com os atributos de qualidade afetados
pelos Smells propostos: complexidade, desempenho e quebra de papéis arquiteturais.
Figura 5 – Divisão do catálogo de Smells por atributos de qualidade afetado.
A figura 5 exibe a lista de Design Smells propostos categorizados de acordo com
o principal atributo de qualidade afetado. Os Design Smells Global Processor , Brain
Reader , Brain Processor e Brain Writer afetam principalmente a complexidade das
aplicações; os Smells Readaholic Component e Amateur Writer degradam o desempenho
dos programas ao realizarem excessivas operações de leitura e escrita de dados; e o Improper
Communication evidencia a quebra de papeis arquiteturais identificando componentes que
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 30
executam processos fora de seus escopos.
Durante todo esse trabalho, estaremos utilizando o termo complexidade para indicar
fatores que podem prejudicar a compreensão, legibilidade e a manutenibilidade do código
fonte das aplicações. Ao se afirmar que um determinado artefato é muito complexo, busca-
se dizer que existe uma dificuldade no processo de manutenção de suas funcionalidades.
Quando nos referirmos a métrica de software de complexidade, ficará explícito no texto
que estamos falando sobre a métrica de complexidade estrutural WMC (Weighted Method
Count).
4.1.1 Global Processor (Classe de Processamento Global)
Definição: A arquitetura de referência utilizada pelo Spring Batch (WARD
DAVE SYER; HASSINE, 2019) define a entidade Item Processor como responsável pelo
processamento dos dados coletados pela aplicaçãobatch. Toda inteligência de negócio
necessária para o processamento de um Step deve ser implementada em um Item Processor .
Porém, é comum a utilização de classes de serviços para implementação de funcionalidades
que podem ser compartilhadas com outros Steps. Idealmente, essas classes devem conter
apenas funcionalidades compartilhadas e que sejam referentes a um determinado contexto
de negócio, para que possam se manter coesas. Uma classe que apresenta o comportamento
de Global Processor possui alto acoplamento, por prover muitas funcionalidades a múltiplos
Item Processors, e baixa coesão, por conter funcionalidades que não se relacionam com
o propósito da classe, basicamente acumula lógica de processamento de vários Steps. A
figura 6 exibe o diagrama de classes UML típico de classes afetadas pelo Global Processor .
Figura 6 – Ilustração do Global Processor
Conforme visto na figura 6, é possível observar que a classe Service possui relacio-
namento com mais de um Item Processor e acumula várias funcionalidades, que em sua
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 31
maioria são utilizadas por apenas um Item Processor . Referente ao contexto do processa-
mento em lotes, a classe Service não apresenta um grau satisfatório de coesão, pois está
armazenando a lógica de processamento de vários Steps, que são unidades independentes
de processamento.
Impacto: O fato da classe afetada acumular funcionalidades de processamento de
vários Steps, que por definição da arquitetura são etapas independentes, contribui para
piorar o grau de coesão da classe. Além do fato de que vários Item Processors necessitarão
referenciar a mesma classe, o que levará ao aumento do grau de acoplamento.
Estratégia de detecção: A detecção de um Global Processor é baseado em duas
características:
1. A classe afetada é uma classe que desempenha papel de provedora de serviços sendo
referenciada por mais de um Item Processor ;
2. A classe afetada apresenta mais de um terço de seus métodos não sendo comparti-
lhados, acessados por apenas um Item Processor .
A primeira etapa para detecção de um Global Processor é encontrar classes que
desempenham papel de classes de serviço e se relacionam com mais de um Item Processor .
Para isso foi utilizada uma variação da métrica Fan-In (LORENZ; KIDD, 1994), que
contabiliza o número de classes que acessam um determinado método, para contabilizar o
número de Item Processors que acessam os métodos da classe analisada (FICP - Fan-IN
Class Processor). Caso uma classe seja referenciada por mais de um Item Processor ,
outra variação da métrica Fan-In, que contabiliza apenas chamadas efetuadas por Item
Processors (FIMP - Fan-In Method Processor), é calculada para cada método da classe. Se
mais que um terço dos métodos forem referenciados por apenas um Item Processor então
a classe analisada pode estar sendo afetada pelo Global Processor . A valor de 1/3 dos
métodos foi escolhido para desconsiderar classes que possuem poucos métodos afetados
pelo Global Processor , pois apesar de possivelmente representar um problema, o número
reduzido de ocorrências não afeta negativamente a legibilidade e a manutenibilidade do
código. A figura 7 exibe o processo lógico para identificação do Global Processor .
Figura 7 – Estratégia de detecção para Global Processor
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 32
Refatoração: Duas propostas de refatoração foram elaboradas para correção do
Global Processor . A primeira proposta é mover os métodos que possuem único acesso
para os Item Processors correspondentes, deixando apenas os métodos compartilhados
na classe de serviço, conforme visto na figura 8. A segunda proposta pode ser utilizada
caso seja necessário manter os métodos de acesso único separados dos Item Processors
correspondentes, por motivos de coesão ou separação de contexto. Deve-se criar uma
classe Service com os métodos de acesso único para cada Item Processor correspondente,
mantendo os métodos compartilhados em uma classe de serviço separada, esse processo é
exibido na figura 9.
Figura 8 – Estratégia 01 de refatoração para Global Processor
Figura 9 – Estratégia 02 de refatoração para Global Processor
É importante observar que as propostas de refatoração para o Global Processor
podem adicionar outros pontos de complexidade no projeto, seja pela introdução de novos
métodos nos Item Processors pela estratégia da figura 8, ou na inclusão de novas classes
de serviços realizada pela estratégia da figura 9.
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 33
4.1.2 Brain Reader (Leitor Complexo)
Definição: Classes Item Readers desempenham o papel de leitores de dados, sendo
responsáveis pela aquisição das informações do processamento. Esses componentes concen-
tram a lógica para leitura de dados, que idealmente deve ser simples e não possuir lógica
de negócio associada, pois o processamento das informações coletadas deve ser responsa-
bilidade dos Item Processors. Um Item Reader afetado pelo Brain Reader apresenta um
elevado grau de complexidade estrutural devido a utilização de muitos fluxos condicionais,
ou apresenta instruções de consultas a repositórios de dados com muitos operadores SQL.
Figura 10 – Exemplo de um Item Reader afetado pelo Brain Reader
A figura 10 exemplifica a ocorrência do Brain Reader . Fica evidente, com a presença
dos múltiplos fluxos condicionais, que a classe pode gerar diferentes versões da instrução
de leitura, tornando-se mais complexa e aumentado a complexidade dos componentes que
realizarão o processamento das informações, que devem estar prontos para processar os
dados obtidos por todas as versões possíveis da instrução de leitura.
Impacto: A presença de lógica com muitos fluxos condicionais, para geração de
consultas dinâmicas, ou mesmo consultas SQL que utilizam muitos operadores podem
aumentar o grau de complexidade estrutural e prejudicar a manutenibilidade do código.
Estratégia de detecção: A estratégia de detecção de um Brain Reader se baseia
na estratégia para detecção da desarmonia de identidade Brain Method desenvolvida por
Lanza e Marinescu (2007), e basicamente verifica o tamanho e a complexidade estrutural
de um Item Reader . Como os Item Readers também podem realizar leitura de fontes de
dados utilizando o padrão de linguagem de consulta SQL, a definição do Brain Method é
estendida nesse trabalho levando-se em consideração também a medida da complexidade
das instruções SQL. A figura 11 exibe a estratégia de detecção para um Brain Reader .
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 34
Figura 11 – Estratégia de detecção para o Brain Reader
1. Classe extensa: Classes longas tendem a serem mais complexas e de difícil ma-
nutenção. A medição do tamanho da classe de leitura será realizada por meio da
métrica número de linhas de código (LOC - Lines of Code).
2. Complexidade estrutural da classe é alta: A presença de estruturas de fluxo
condicional pode sugerir a utilização de consultas dinâmicas que serão geradas
de acordo com regras de negócio. Incluir consultas dinâmicas pode prejudicar a
manutenção de todo o processamento em lotes, pois a cada execução, um conjunto
de dados diferente pode estar sendo processado, e consequentemente mais estruturas
condicionais serão exigidas para atender os diferentes conjuntos de dados, aumentando
a complexidade de toda a aplicação batch. Para calcular a complexidade estrutural
será utilizada a soma estatística da complexidade ciclomática de todos os métodos
da classe (WMC - Weighted Method Count).
3. Possui métodos com estruturas de aninhamento profundo: Semelhante a
observação do item anterior, ocorrência de estruturas de controle de fluxo com um
aninhamento elevado evidenciam a aplicação de lógica complexa no processo de
leitura, diminuindo o grau de legibilidade e manutenção do código. Para medir o
grau de aninhamento será utilizada a métrica MAX NESTING.
4. Métodos utilizam muitos operadores SQL: A ocorrência deinstruções SQL
complexas pode sugerir a transferência de regras de negócio do código da aplicação
para a consulta. Em alguns casos, a correspondência entre as instruções de código Java
e SQL não é direta e intuitiva, acabando por adicionar uma carga de complexidade
maior comparada com a versão correspondente em código Java. Para calcular o grau
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 35
de complexidade das instruções de consulta, será computado o total de operadores
SQL utilizados.
Refatoração: Duas estratégias de refatoração são sugeridas. A primeira consiste
na criação de um novo Step para cada versão da instrução de consulta gerada. A segunda,
transferir a complexidade estrutural de criação da consulta para filtros de verificação nos
Item Processors. A primeira estratégia, vista na figura 12, é mais interessante, pois irá
gerar Steps com leitores mais simples sem a necessidade de transferir a complexidade
estrutural para os Item Processors.
Figura 12 – Estratégia de refatoração para o Brain Reader
Apesar de gerar classes mais simples, a estratégia de refatoração da figura 12 eleva a
complexidade do projeto, pois adiciona novos fluxos de processamento e cria novas classes.
4.1.3 Brain Processor (Processador Complexo)
Definição: Os Item Processors concentram toda a lógica de processamento das
aplicações batches, e toda inteligência de negócio aplicada aos dados deve ser implementada
nesses componentes. Apesar de figurarem como um centro de inteligência da aplicação, essas
classes devem manter o controle da complexidade balanceado, evitando centralizar muita
inteligência de negócio e obter muita responsabilidade. Um Item Processor afetado pelo
Brain Processor se apresenta como uma classe extensa, com baixa coesão ou complexidade
estrutural alta.
Impacto: O tamanho extenso e a presença de métodos complexos prejudicam a
compreensão do código implementado, somando-se o acúmulo de responsabilidades que
degradam a coesão e consequentemente o grau de manutenibilidade da classe.
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 36
Estratégia de detecção: A estratégia de detecção do Brain Processor toma por
base a desarmonia de identidade Brain Class proposta por Lanza e Marinescu (2007) e o
Bad Smell Large Class proposto por Fowler e Beck (1999). A ideia principal é encontrar
classes que destoam das demais em relação ao tamanho, complexidade estrutural e coesão.
A figura 13 exibe a estratégia de detecção de um Brain Processor .
Figura 13 – Estratégia de detecção para o Brain Processor
1. Classes excessivamente longas: Semelhante ao Brain Reader , a métrica utilizada
para calcular o tamanho de uma classe será o número de linhas de código (LOC -
Lines of Code).
2. Complexidade estrutural alta: Para calcular a complexidade estrutural de um
Item Processor será utilizada a soma das complexidades ciclomáticas dos métodos
(WMC - Weighted Method Count).
3. Estruturas com aninhamento profundo: O grau de aninhamento das estruturas
de controle será dado pela métrica MAX NESTING, selecionando as classes que
possuírem pelo menos um método com aninhamento maior que a média calculada
para os Item Processors da aplicação.
4. Classes com baixa coesão: Classes coesas possuem membros com uma relação
forte, o que facilita a manutenção, pois fica evidente qual funcionalidade está sendo
entregue com maioria dos seus componentes trabalhando em conjunto para entrega
dessa funcionalidade. Esse comportamento auxilia na compreensão do código e
permite um grau de reusabilidade mais elevado. Classes com baixa coesão são difíceis
de entender e reutilizar, porque muitas funcionalidades são oferecidas e não existe
uma forte relação entre seus componentes. Para medir o grau de coesão de uma classe
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 37
será utilizada a métrica LCOM (Lack Of Cohesion), que calcula o número relativo
de pares de métodos que acessam ao menos um atributo em comum da classe.
Refatoração: A estratégia de refatoração para um Brain Processor consiste na de-
composição de responsabilidade. A primeira ação será verificar se o Step com processamento
complexo pode ser decomposto em Steps mais simples, simplificando o processamento
individual. Caso não seja possível a decomposição dos Steps, a arquitetura do Spring Batch
disponibiliza um mecanismo de composição de Item Processors, onde o Item Processor
principal será uma composição de Item Processors mais simples que serão executados
em uma ordem pré-determinada. Esse mecanismo permite distribuir a complexidade do
componente inicial para componentes mais simples e coesos. A figura 14 exibe um diagrama
de classes com a aplicação dessa refatoração. Deve-se observar que essa estratégia simplifica
as classes de processamento, mas adiciona mais complexidade ao processo com o aumento
do número de classes.
Figura 14 – Estratégia de refatoração para o Brain Processor
4.1.4 Brain Writer (Escritor Complexo)
Definição: Os Item Writers são responsáveis pela persistência das informações
processadas. O conteúdo recebido por um Item Writer deve estar processado para que
apenas o armazenamento em um repositório de dados seja necessário. Um Item Writer
afetado pelo Brain Writer se apresenta como uma classe extensa, com complexidade
estrutural elevada ou instruções de manipulação de repositório de dados extensas e
complexas.
Impacto: Assim como nos Smells anteriores a complexidade é o principal agravante
em um Brain Writer . Métodos de escrita ou instruções de armazenamento longas e
complexas afetam diretamente o grau de dificuldade de manutenção da aplicação.
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 38
Estratégia de detecção: Semelhante ao Brain Reader , a estratégia de detecção
utilizada será baseada na extensão e complexidade estrutural da classe e das instruções de
armazenamento de dados SQL. A estratégia para detecção do Brain Writer pode ser vista
na figura 15.
Figura 15 – Estratégia de detecção para o Brain Writer
1. Classes extensas: A medição do tamanho das classes será realizada por meio da
métrica número de linhas de código (LOC - Lines of Code).
2. Complexidade estrutural da classe é alta: Para o cálculo da complexidade
estrutural dos métodos será utilizada a soma das complexidades ciclomáticas (WMC
- Weighted Method Count).
3. Classe possui métodos com estruturas muito aninhadas: O grau de aninha-
mento será adquirido pela métrica MAX NESTING.
4. Métodos utilizam muitos operadores SQL: Para calcular o grau de complexi-
dade das instruções de armazenamento, será computado o total de operadores SQL
utilizados.
Refatoração: A refatoração de um Brain Writer deve ser iniciada verificando-se o
principal fator responsável pelo aumento da complexidade. Caso seja observada a existência
de lógica de negócio entre as instruções de armazenamento, será necessário a transferência
dessa lógica para os Item Processors, que são os reais responsáveis pelo processamento
das informações. Ou, se o método de armazenamento realiza a escrita dos dados em mais
de uma fonte de dados ou tabela de banco de dados, o Spring Batch disponibiliza um
mecanismo de composição de Item Writers, que semelhante aos Item Processors permite
Capítulo 4. Design Smells em Aplicações com Spring Batch Framework 39
compor escritores para que sejam executados em uma ordem pré-determinada, distribuindo
a complexidade estrutural da classe original em classes menores, com índices mais baixos
de complexidade estrutural e mais coesas, conforme observado no diagrama da figura 16.
Figura 16 – Estratégia de refatoração para o Brain Writer
Semelhante a proposta de refatoração do Brain Processor , a refatoração do Brain
Writer pode elevar o grau de complexidade do projeto com a adição de novas classes de
escrita. Ou aumentar a complexidade estrutural de seu Item Processor correspondente, ao
se transferir a lógica de negócio, podendo em casos mais extremos induzir a criação de um
Brain Processor .
4.1.5

Continue navegando