ATENÇÃO: TEXTO QUASE EMOTIVO SOBRE DESENVOLVIMENTO DE SISTEMAS. BASTANTE BLABLABLA FRENTE. CUIDADO.
Trabalhando em um projeto pessoal me ocorreu: Será que preciso mesmo dividir a responsabilidade do sistema, dividir as camadas e ainda me preocupar em baixo acoplamento e com semântica?
Vou explicar-me melhor: Meus projetos pessoais são a oportunidade de colocar em prática as várias idéias e teorias sobre desenvolvimento e arquitetura, que se bem aplicados passarão para os proximos clientes. É a chance de fazer o sistema perfeito, de modo que uma engenharia reversa para UML resultaria numa obra de Picasso. São projetos reais, onde tenho a chance de testar frameworks, metodologias e etc.
Quer dizer, são projetos que geralmente nunca termino. Por que quase sempre aparece uma idéia legal para testar. Mas estou perdendo o foco do texto...
Nesse projeto aplico Desenvolvimento guiado a testes(O TDD), divido as funcionalidades em pequenos métodos, baixo acoplado, re-uso tudo que posso... sempre refatorando, me preocupando se as classes não ficam complexas demais, se não fogem a sua responsabilidade. “Será que um Repositório pode usar outro Repositório?”, “Essa uma pesquisa em massa no banco esta no escopo dessa classe?”, “Esse nome transmite o sentido do método? E esse retorno é apropriado?” e etc... assim nos mínimos detalhes. Ai parei para me perguntar, será que preciso disso tudo?
Quer dizer, especialmente para começar no TDD (desenvolvimento guiado a testes...) é bem chato, é um começo difícil. Por que as classes as vezes não são fáceis de testar, são muitos testes, muitos casos a cobrir, tem que ter um banco de dados para isso... são várias “pedras no caminho”.
As vezes parece que seria muito mais rápido escrever uma pagina para lidar com cada requisição, acessar o BD direto ali e simplesmente fazer acontecer a mágica do sistema... não é mais fácil? Tudo esta no escopo, me guiar pela requisição e pelo retorno apenas. Não é mais fácil?
Recebi de braços abertos e sem defesa a resposta, como uma flecha varando meu peito, fria: “NEM FODENDO NÃO É MAIS FÁCIL!”. Senta que lá vem mais história.
Essa semana mesmo estava fazendo manutenção numa aplicação mais antiga que desenvolvi. É um ERP, uso crítico da empresa, na época ainda estava aprendo OO, então mal tinha esboço de classes naquilo ( Só tinha um classe para o BD, e os modelos que a estendiam... modelo estendendo BD! Triste mesmo...). E o pior que era organizada até, exista um quase MVC por trás da aplicação, mas conforme adcionava funcionalidades as pressas, tudo ia para debaixo dos panos.
As responsabilidades não eram bem dividas, não tinha um rotina de testes básica, camadas são para os fracos. Ou seja, o sistema se tornou imprevisível! A cada clique eu temia que o banco de dados fosse para o espaço e meu processador fritasse. Para garantir que uma nova regra de negócio acontece por todo o sistema, eram várias alterações, em vários lugares as vezes desconexos. “Adicionar porcentagem de aproveitamento: arquivo salvar_conta, classe conta (nos 5 loops dos 3 métodos), arquivo benchmark ( no loop 2, 5 e na exibição).”

Numa mesma aplicação desenvolvida pouco tempo depois, ainda não tinha os testes automáticos e o mesmo cuidado de hoje, mas já tinham camadas, modelagem, interfaces... é moleza. “Quer mudar uma posição da foto, vai na View”, “As imagens não estão armazenando corretamente, será no uploader ou no tratamento de imagens?”,”Uhm, não esta recuperando esse campo do BD, abre o DAO.”, é padrão, tem poucas dúvidas e a implementação é rápida, acha-se os problemas facilmente.
O conhecimento ganhado é gradativo: OO, camadas, Repositórios, frameworks, Testes... quanto mais é aplicado, mais fácil é dar manutenção. MANUTENÇÃO é a palavra. Só parece que é mais fácil fazer sem preocupação, mas isso só vai ficar legal por uma ou duas páginas. Quando o sistema começa a se conectar, quando começam a surgir alterações(e sempre, SEMPRE surgem!) ai que faz falta a boa modelagem.
Obviamente também tem que tomar cuidado com o “overengeneering”, modelar demais pode ser perigoso e criar correntes de responsabilidades sem sentido entre outros. Tem que estar sempre em busca do ponto de equilibrio.
Especialmente de um tempo para cá, quando comecei a aplicar o TDD, depois de muito lutar contra(tenho que admitir), comecei a ver os benefícios. É muito mais que garantir que os métodos estão retornando certo... é a chance de garantir a boa implementação do sistema. Os testes são as métricas do bom código.
Se esta difícil escrever uma rotina de testes consistente, é um sintoma que a modelagem não esta muito boa: Os métodos estão com muita responsabilidade, ou tudo esta muito acoplado. Se a responsabilidade esta bem divida, há bastante re-uso e os métodos fazem sentido, é fácil bolar os testes.
Os testes são também uma boa documentação. Quer saber como um classe deve se comportar, como ela será usada? Veja como foi testada, quais os pontos críticos do teste.
Quer saber qual implementação é mais rápida, ou tem melhor performance? Coloque marcadores nos testes, contadores. Adicione uma ferramenta de profiling. Você vai ter a garantia que mudou a implementação, o sistema esta funcionando igual, e saber se ficou mais rápido ou não.
Uma análise boa por exemplo é: E se eu mudar de framework(ou adotar um) para área XPTO, o quanto isso vai afetar o sistema? Bom, a mudança deve ser transparente, a dependência do framework e infraestrutura em geral deve ser bem separada. E os testes devem garantir que tudo continua funcionando da mesma forma após a mudança.
É, foi um desabafo sim, mas foi sincero. Seguimos aprendendo ;D
- Comments





