Refatorar é o processo de mudar a estrutura interna do software sem alterar seu comportamento externo. Esta técnica evita que o software se desgaste durante a vida útil do mesmo. Com esta técnica você consegue melhorar seu software sem que os clientes se sintam perdidos em cada alteração que você fizer.
Este tema é muito útil para sistemas com códigos desorganizados, pois a refatoração vai ajudar a melhorar o entendimento do código além de evitar a inclusão de novos defeitos durante futuras modificações. O artigo da edição anterior apresentou os conceitos básicos da orientação a objetos sem se preocupar com a arquitetura que estava sendo criada a aplicação de agendamento de tarefas – sem aplicar padrões de projetos. Já este artigo começa a refatorar o código da primeira versão a fim de corrigir os problemas de engenharia existentes.
Na parte anterior deste artigo a primeira versão do agendador ficou pronta, mas com uma série de problemas. Não estamos falando de erros, pois a aplicação funcionava sem gerar erro algum. Estamos falando de problemas estruturais – alguns chamariam de problemas administrativos. Embora o agendador esteja cumprindo com sua obrigação de executar tarefas em horários pré-programados, estruturalmente ele está em péssimas condições. Não é necessário observar muito para perceber os problemas de engenharia presentes no código. No próximo parágrafo você encontra uma breve descrição dos problemas que o código do sistema possui. Desta maneira, se você ainda não leu a parte anterior desta série, poderá ler este artigo sem ficar perdido no assunto.
O maior problema da primeira versão é que toda a lógica do programa está dentro da classe do formulário principal. Tudo está neste formulário: salvar tarefas, salvar agendamentos, monitorar os agendamentos, cálculo da próxima execução de uma tarefa, cálculo da próxima execução de um agendamento, cálculo para saber se está na hora de executar uma tarefa e até mesmo o método para executar as tarefas.
“Bad smells in code”
Quando dissemos que tudo estava dentro da classe do formulário, não estávamos exagerando. Repare nos itens que citamos no último parágrafo da introdução: o que mais a primeira versão faz além do que foi citado lá? Não faz mais nada. Tudo que o agendador faz foi escrito dentro da classe do formulário. Embora existam mais duas classes – Tarefa e Agendador – nenhuma vantagem da orientação a objetos foi usada. A classe do formulário está muito grande e cheia de desvios feitos através de testes (instruções IF). Qualquer alteração no programa resultará em uma modificação na classe do formulário e como esta classe está cheia de responsabilidades interligadas, qualquer modificação feita nela significa que outra parte da aplicação pode começar a gerar erros por conta disto – por isto todas as funções da aplicação devem ser testadas novamente.
Estes são um dos motivos para criar um sistema cujas responsabilidades estão separadas em classes, porém, existem muitos outros. Imagino eu que, se você já leu até aqui é porque você conhece os problemas de uma codificação ruim e deve estar mais interessado em como fazer da maneira certa do que nas consequências de se fazer da maneira mais fácil. Por isto vamos direto ao ponto. Veja o que é e como refatorar um código, usando como exemplo a classe do formulário do agendador.
Vantagens das classes com responsabilidade única
A classe do formulário está cheia de responsabilidades e isto não é bom. Isto é tão ruim que até existe um princípio da orientação a objetos que trata especificamente disto, chama-se: Princípio da Responsabilidade Única. Para seguir este princípio é preciso identificar todas as responsabilidades de uma classe e separar estes objetivos em mais classes a qualquer custo. Sim, é mais fácil falar do que fazer. O princípio diz o que deve ser feito, porém, como é que se faz para identificar e separar as responsabilidades de uma classe? Antes de aprender como faz, veja as vantagens que isto vai trazer.
A primeira vantagem é que quando qualquer classe possui apenas uma responsabilidade, isto significa que ela também possui apenas uma única razão para mudar. Quando as classes do seu sistema possuem apenas uma única responsabilidade, você consegue fazer alterações, adicionar ou remover novos comportamentos no sistema sem ficar preocupado se o resto do sistema vai ser influenciado, pois cada classe do sistema tem sua responsabilidade e sabe como realizá-la indiferentemente do que acontece com as demais classes. Em outras palavras é possível alterar o sistema sem precisar testar o sistema inteiro novamente: você vai precisar testar somente a parte que foi alterada ou adicionada.
...