Este é um post disponível para assinantes MVPEste post também está disponível para assinantes da .net Magazine DIGITAL ou para quem possui Créditos DevMedia. Clique aqui para saber mais!
Artigo .net magazine 72 - Refactoring na prática
Refactoring trata-se de um processo que tem como principais objetivos tornar o código mais legível e com maior manutenibilidade. Menciona-se processo, pois refactoring não consiste em apenas mudar o código que já funciona, pois quando há qualquer tipo de alteração, há riscos de introdução de novos bugs. Refactoring é algo maior, que envolve pequenos passos, testes, disciplina e força de vontade. Este artigo irá demonstrar de forma pragmática como um processo de refactoring deve ser conduzido.
.net Magazine 72
[Artigo já está disponível no Leitor Digital DevMedia®. Clique aqui para acessá-lo]
> Clique aqui para ler todos os artigos da .net Magazine 72
[Artigo já está disponível no Leitor Digital DevMedia®. Clique aqui para acessá-lo]
> Clique aqui para ler todos os artigos da .net Magazine 72
Refactoring na prática
Torne seu código mais simples, organizado e legível
Martin Fowler, famoso engenheiro de software, no livro “Refactoring, Improving the Design of Existing Code”, define refactoring em dois contextos, os quais em tradução livre, reporto a seguir:
“Refactoring: alteração realizada na estrutura interna do software para torná-lo fácil de entender e barato para modificar, sem alterar o comportamento externo.
Refactor: reestruturar o software aplicando um conjunto de refatorações, sem alterar o comportamento externo.”
Acredito que o conceito tenha ficado claro, no entanto é interessante destacar os possíveis cenários nos quais a refatoração pode ser aplicada:
• Sistemas legados: Grande dor de cabeça da maioria dos desenvolvedores. A manutenção é sempre agressiva e desanimadora devido aos mais variados motivos: código duplicado, lógica de negócio duplicada, o fato do código já ter passado pela mão de dezenas de desenvolvedores, nomes de funções ou classes já não condizem com os reais objetivos, entre outros;
• Novos sistemas: Um pouco contraditório, não? Explico: No TDD, que no meu entendimento é uma técnica de design, temos os seguintes passos:
o Adicionar um teste;
o Executar o teste. Ele falhará;
o Escrever o código para o teste passar;
o Rodar novamente o teste. Ele passará;
o Refatorar o código;
o Repetir quantas vezes forem necessárias, até você atingir o design desejado.
No passo “Escrever o código para o teste passar”, temos como objetivo inicial atender a regra de negócio que o teste valida, portanto, não nos preocupamos com o design, de qualquer forma, temos a premissa do refactoring, o código existente. Com o código aderente a regra, ou seja, um comportamento desejável, refinamos o código(refactoring) e rodamos o teste novamente até que ele passe. Como resultado, temos o código melhorado e com o mesmo comportamento.
Para entendendermos o processo de refactoring, vamos a um exemplo prático.
Nota do DevMan
TDD, ou Test-Driven Development, é uma das práticas do XP (Extreme Programming). Basicamente, a ideia é que primeiro sejam desenvolvidos os testes para só então escrever o código necessário para que o teste passe. Com os testes devidamente criados, temos a segurança necessária para então refatorar o código com a segurança que os testes promovem de que não quebraremos nenhuma funcionalidade.
Melhorando o design de uma aplicação real
Para o exemplo, vou utilizar o módulo de um sistema que eu mesmo fiz há alguns anos e que tornou-se complicado de manter. O objetivo do módulo é efetuar a carga de cotações históricas de ações da Bovespa, disponibilizada através de um arquivo texto posicional. A mecânica deste módulo funciona da seguinte forma:
• Usuário entra no site da Bovespa, loga-se e baixa o arquivo de cotações históricas. Ele pode selecionar, por exemplo, as cotações do dia anterior. O arquivo é baixado no formato .zip;
• Usuário loga-se no sistema e realiza o upload do arquivo de cotações;
• Uma aplicação .NET 2.0 do tipo Windows Service fica monitorando um diretório (que foi parametrizado em arquivo de configuração) e, quando um arquivo com a extensão .zip é detectado, o serviço abre, descompacta e disponibiliza o arquivo .TXT que estava dentro do zip;
• Sistema interpreta o arquivo conforme o layout da Bovespa e grava em banco de dados as cotações.
A solução está distribuída em quatro assemblies, como mostra a Figura 1. Na Figura 2 temos o diagrama de classes.
Figura 1. Diagrama de componentes da solução atual
Figura 2. Diagrama de classes da solução
Antes de iniciarmos o refactoring utilizando o Visual Studio 2008 Team Suite, vamos coletar as métricas do código da solução atual. Para capturar as métricas, clique com o botão direito sobre cada projeto e selecione a opção “Calculate Code Metrics”. Após o refactoring, vamos rodar novamente e avaliar os resultados. A Figura 3 mostra a análise inicial.
Figura 3. Métricas de código
Nota: As métricas de código ajudam o desenvolvedor a avaliar a complexidade, reuso, padronização e outras características do sistema.
O refactoring para este artigo será realizado nas classes BO.Cotacao, BE.Cotacao e DAL.Cotacao. A aplicação atual não tem nenhum teste automatizado, me deixando inseguro para iniciar qualquer tipo de incursão no código pois, afinal, esta é uma aplicação que já funciona.
No Listagem 1 temos o trecho de código do Windows Services que inicia o processo de importação.
Listagem 1. Trecho de código onde o processamento é iniciado
// Define the event handlers.
private static void OnChanged(object source, FileSystemEventArgs e)
{
try
{
EventLog.WriteEntry("AMAWEB", "Início da carga do arquivo " + e.FullPath + " !", EventLogEntryType.Information);
"
ATENÇÃO! A exibição deste artigo foi interrompida.
Este é um post disponível para assinantes MVP
Torne seu código mais simples, organizado e legível
Martin Fowler, famoso engenheiro de software, no livro “Refactoring, Improving the Design of Existing Code”, define refactoring em dois contextos, os quais em tradução livre, reporto a seguir:
“Refactoring: alteração realizada na estrutura interna do software para torná-lo fácil de entender e barato para modificar, sem alterar o comportamento externo.
Refactor: reestruturar o software aplicando um conjunto de refatorações, sem alterar o comportamento externo.”
Acredito que o conceito tenha ficado claro, no entanto é interessante destacar os possíveis cenários nos quais a refatoração pode ser aplicada:
• Sistemas legados: Grande dor de cabeça da maioria dos desenvolvedores. A manutenção é sempre agressiva e desanimadora devido aos mais variados motivos: código duplicado, lógica de negócio duplicada, o fato do código já ter passado pela mão de dezenas de desenvolvedores, nomes de funções ou classes já não condizem com os reais objetivos, entre outros;
• Novos sistemas: Um pouco contraditório, não? Explico: No TDD, que no meu entendimento é uma técnica de design, temos os seguintes passos:
o Adicionar um teste;
o Executar o teste. Ele falhará;
o Escrever o código para o teste passar;
o Rodar novamente o teste. Ele passará;
o Refatorar o código;
o Repetir quantas vezes forem necessárias, até você atingir o design desejado.
No passo “Escrever o código para o teste passar”, temos como objetivo inicial atender a regra de negócio que o teste valida, portanto, não nos preocupamos com o design, de qualquer forma, temos a premissa do refactoring, o código existente. Com o código aderente a regra, ou seja, um comportamento desejável, refinamos o código(refactoring) e rodamos o teste novamente até que ele passe. Como resultado, temos o código melhorado e com o mesmo comportamento.
Para entendendermos o processo de refactoring, vamos a um exemplo prático.
Nota do DevMan
TDD, ou Test-Driven Development, é uma das práticas do XP (Extreme Programming). Basicamente, a ideia é que primeiro sejam desenvolvidos os testes para só então escrever o código necessário para que o teste passe. Com os testes devidamente criados, temos a segurança necessária para então refatorar o código com a segurança que os testes promovem de que não quebraremos nenhuma funcionalidade.
Melhorando o design de uma aplicação real
Para o exemplo, vou utilizar o módulo de um sistema que eu mesmo fiz há alguns anos e que tornou-se complicado de manter. O objetivo do módulo é efetuar a carga de cotações históricas de ações da Bovespa, disponibilizada através de um arquivo texto posicional. A mecânica deste módulo funciona da seguinte forma:
• Usuário entra no site da Bovespa, loga-se e baixa o arquivo de cotações históricas. Ele pode selecionar, por exemplo, as cotações do dia anterior. O arquivo é baixado no formato .zip;
• Usuário loga-se no sistema e realiza o upload do arquivo de cotações;
• Uma aplicação .NET 2.0 do tipo Windows Service fica monitorando um diretório (que foi parametrizado em arquivo de configuração) e, quando um arquivo com a extensão .zip é detectado, o serviço abre, descompacta e disponibiliza o arquivo .TXT que estava dentro do zip;
• Sistema interpreta o arquivo conforme o layout da Bovespa e grava em banco de dados as cotações.
A solução está distribuída em quatro assemblies, como mostra a Figura 1. Na Figura 2 temos o diagrama de classes.
Figura 1. Diagrama de componentes da solução atual
Figura 2. Diagrama de classes da solução
Antes de iniciarmos o refactoring utilizando o Visual Studio 2008 Team Suite, vamos coletar as métricas do código da solução atual. Para capturar as métricas, clique com o botão direito sobre cada projeto e selecione a opção “Calculate Code Metrics”. Após o refactoring, vamos rodar novamente e avaliar os resultados. A Figura 3 mostra a análise inicial.
Figura 3. Métricas de código
Nota: As métricas de código ajudam o desenvolvedor a avaliar a complexidade, reuso, padronização e outras características do sistema.
O refactoring para este artigo será realizado nas classes BO.Cotacao, BE.Cotacao e DAL.Cotacao. A aplicação atual não tem nenhum teste automatizado, me deixando inseguro para iniciar qualquer tipo de incursão no código pois, afinal, esta é uma aplicação que já funciona.
No Listagem 1 temos o trecho de código do Windows Services que inicia o processo de importação.
Listagem 1. Trecho de código onde o processamento é iniciado
// Define the event handlers.
private static void OnChanged(object source, FileSystemEventArgs e)
{
try
{
EventLog.WriteEntry("AMAWEB", "Início da carga do arquivo " + e.FullPath + " !", EventLogEntryType.Information);
"
ATENÇÃO! A exibição deste artigo foi interrompida.
Este é um post disponível para assinantes MVPEste post também está disponível para assinantes da .net Magazine DIGITAL ou para quem possui Créditos DevMedia. Clique aqui para saber mais!

Você está em:
canal .net
Publicidade
Fabio Margarito Martins De Barros
Space do autor
Atua como arquiteto de software em uma grande instituição financeira. Trabalha com .NET desde as versões beta e é aficionado por patterns e boas práticas no design de aplicações. Membro ativo do grupo www.dotnetarchitects.net, formado em Ciências da Computação.
Space do autor


0
0
