Como escrever um bom código?

Olá!

No começo do ultimo mês de maio tive a oportunidade de desenvolver um software “do zero”. Desta forma, fui responsável pela coleta de requisitos, modelagem, programação e tudo o mais. O software foi desenvolvido para a plataforma web utilizando a arquitetura em camadas. Sendo assim, eu tenho um projeto Dal (Data Access Layer), outro Bll (Business Logic Layer), outro Dto (Data Transfer Object) e, claro, o projeto web responsável pela UI. Acredito que eu tenha, pelo menos o básico, dos conceitos de OO bem sólidos em minha mente e que consegui aplicá-los neste projeto.

O software não consiste em nada mais que cadastros, consultas e relatórios. Inicialmente estavam previstom três módulos, e agora já tenho cinco módulos completos. É o típico projeto em que os requisitos mudam a todo momento e incrementos e adaptações são sempre necessários. Eu não estou com grandes problemas para customizá-lo ou estendê-lo, embora às vezes algo relativamente simples demore um pouco para fazer.

Pelo fato de sempre estar atendendo demandas rápidas dos usuários, sinto que a qualidade do código-fonte deste software tem se degradado. E temo que futuramente ocorram tantas mudanças que tornem o código ilegível.

Eu tenho consciência que a qualidade do código-fonte é importante, tanto para mim quanto para a equipe, e que um trabalho de refatoração será necessário. Eu até já comecei a escrita de uma segunda versão do software focando na legibilidade do código, mas gostaria de evitar agora os mesmos erros do passado. Portanto peço para todos que me ajudem com dicas, materiais, metodologias, etc… Em resumo, qualquer coisa que me ensine a escrever um software que resista às mudanças e ao tempo.

[]'s

[quote=Júlio Murta]Olá!

No começo do ultimo mês de maio tive a oportunidade de desenvolver um software “do zero”. Desta forma, fui responsável pela coleta de requisitos, modelagem, programação e tudo o mais. O software foi desenvolvido para a plataforma web utilizando a arquitetura em camadas. Sendo assim, eu tenho um projeto Dal (Data Access Layer), outro Bll (Business Logic Layer), outro Dto (Data Transfer Object) e, claro, o projeto web responsável pela UI. Acredito que eu tenha, pelo menos o básico, dos conceitos de OO bem sólidos em minha mente e que consegui aplicá-los neste projeto.

O software não consiste em nada mais que cadastros, consultas e relatórios. Inicialmente estava previsto três módulos, e agora já tenho cinco módulos completos. É o típico projeto em que os requisitos mudam a todo momento e incrementos e adaptações são sempre necessários. Eu não estou com grandes problemas para customizá-lo ou estendê-lo, embora às vezes algo relativamente simples demore um pouco para fazer.

Pelo fato de sempre estar atendendo demandas rápidas dos usuários, sinto que a qualidade do código-fonte deste software tem se degradado. E temo que futuramente ocorram tantas mudanças que tornem o código ilegível.

Eu tenho consciência que a qualidade do código-fonte é importante, tanto para mim quanto para a equipe, e que um trabalho de refatoração será necessário. Eu até já comecei a escrita de uma segunda versão do software focando na legibilidade do código, mas gostaria de evitar agora os mesmos erros do passado. Portanto peço para todos que me ajudem com dicas, materiais, metodologias, etc… Em resumo, qualquer coisa que me ensine a escrever um software de resista às mudanças e ao tempo.

[]'s[/quote]

Alguns livros sobre o assunto:

(ainda não consegui ler todos rsrsrs, mas são as principais referências)

Esse sentimento de que o código poderia estar melhor escrito é absolutamente normal, e saudável, pois significa que você está fazendo o seu melhor.

Escrever código correto, legível, desacoplado e elegante é uma tarefa árdua. Mesmo que você conheça os princípios de OO, essa tarefa requer muita prática e experiência. Nesse aprendizado, um colega que possa te ajudar a revisar o seu código faz muita diferença.

O cuidado que você deve ter é de não ficar reescrevendo o mesmo código diversas vezes. Uma vez que o módulo (caso de uso, user story, tela, etc.) estiver funcionando você deve evitar ficar reescrevendo a mesma coisa para suas entregas não atrasarem.

A minha sugestão é que você incorpore as práticas de clean code aos poucos. Escolha uma determinada prática e exercite-a até que ela fique internalizada. Por exemplo, comece seguindo convenções de nomenclatura, quando sentir que isso passar a fluir, comece a escolher melhores nomes para variáveis, depois melhores nomes para classes e funções … e assim por diante. O que você não deve fazer é ficar reescrevendo o mesmo código diversas vezes tentando atingir a perfeição, pois além de você não conseguir atingí-la, você corre o risco de atrasar suas entregas ou ainda inserir bugs em código que funcionava.

Meu amigo, o seu pedido cabe um livro inteiro de respostas que poderiam ser dadas. Acho que começar a estudar Padrões de Projeto é um excelente começo pra você poder passar pela tempestade eterna que se chama manutenção de software…

Máxima de um Software: “REQUISITOS SEMPRE (SEMPRE, SEMPRE, SEMPRE, etc.) MUDAM”.

Meus 2 centavos:

http://www.submarino.com.br/produto/6983188/livro-codigo-limpo-habilidades-praticas-do-agile-software

http://www.submarino.com.br/produto/177684/livro-padroes-de-projeto

Abs []

E para ajudar com qualidade de código que se “degrada”:

Na verdade, eu ficaria preocupado se olhasse algum código antigo meu e pensasse “nossa, eu programa bem pra kct!”. Mostra que eu desaprendi no processo.

Além disso, Julio, lembre-se que ao final do código muitos requisitos incertos ficam conhecidos. Então, alguns trechos que as vezes começaram tortuosos poderiam realmente ser melhor escritos, ou simplificados, com a informação em mãos.

O que não significa que quem os escreveu, sem essa informação, estivesse fazendo um mau trabalho.

Por isso, além de uma boa análise “top-down”, é importante conhecer práticas de refatoração e codificação que melhorem o projeto no sentido “bottom-up”.

Escrever código que “resista ao tempo” é realmente algo complicado. As dicas acima dos nossos colegas, realmente ajudam muito a desenvolver um código de qualidade. Particularmente, recomendaria vc começar a ler hoje mesmo o Refactoring do Martin Fowler e um livro de Design Patterns, caso não tenha lido nenhum dos dois.

Mas o foco desses livros é ajudar a melhorar a qualidade do seu código. Para escrever sistemas em que o código “resista ao tempo” e não vire uma “macarronada” devido a manutenções e outras mudanças, recomendo a vc aplicar metodologias de engenharia ágil, como testes automatizados e integração contínua. Assim quando vc perceber que ao inserir determinada feature no sistema o código/design pode ficar ruim, vc deve refatorar o que achar necessário e utilizar os testes automatizados para ter garantia que o sistema continua funcionando corretamente. Caso algum desenvolvedor da equipe quebre os testes, o servidor de integração contínua avisará a todos da equipe, permitindo que uma ação seja tomada imediatamente após o problema ser detectado e diminuindo a possibilidade de inserção de bugs no sistema. E também dessa forma vc não precisa ter que reescrever o sistema inteiro, toda hora que achar que o código está ruim, o que é inviável na grande maioria dos casos.

Você ainda pode se deparar com outros problemas adiante, software as vezes pode se tornar algo “imprevisível” e não existe bala de prata. Mas essa abordagem tem nos ajudado bastante aqui na empresa onde trabalho, e após alguns anos de experiência e muitos projetos, tenho a certeza de que hoje, esse é o caminho a seguir.

Procure fazer um código mais coeso com baixo acoplamento.

isso te ajudar no crescimento do projeto. SEMPRE!

Eu estou utilizando TDD neste projeto. Embora eu tenha começado a escrever testes apenas por curiosidade, notei que o código fica menos dependente da interface. O problema é que, pelo menos comigo, o tempo de desenvolvimento aumenta =/

Como você mesmo notou, aumenta o tempo de desenvolvimento sim. Então avalie se isso não vai atrapalhar mais do que ajudar. Para o código ficar independente de interface do usuário não precisa usar TDD.

Perde tempo na primeira versão, mas poupa bastante na manutenção. A primeira versão já sai com menos erros, e fica mais fácil refatorar o código e não inserir novos erros no processo.

Lembre-se que testes automatizados é uma coisa e TDD é outra. Você não precisa necessariamente escrever o teste antes do código, o que é pregado pelo TDD. Inclusive, muitas pessoas fazem testes mas não utilizam TDD, como por exemplo o David Hanson, criador do ruby on rails: http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html.

Eu particulamente não uso muito TDD, poucas vezes sinto necessidade de escrever o teste antes do código, o que não significa que meu código não vai ter cobertura de teste ou que vai ter menos qualidade.

Sobre a questão do tempo, é normal vc demorar mais, principalmente no inicio do projeto, mas vc tb vai perceber que vai facilitar bastante a manutenção e o pessoal da equipe vai sentir mais segurança ao fazer refatorações. Quase ninguém tem coragem de refatorar código sem teste, geralmente o pessoal coloca “mais um if” ali e tá tudo certo.

Perde tempo na primeira versão, mas poupa bastante na manutenção. A primeira versão já sai com menos erros, e fica mais fácil refatorar o código e não inserir novos erros no processo.[/quote]
Em sistemas de informação é comum sempre ter “primeira versão” de algo, seja novas telas, novas regras, mudanças profundas no processo, etc, onde por consequência entra esse tempo envolvendo TDD. Mas concordo que esse tempo gasto vira investimento se for resolver problemas que realmente existam, e problemas mesmo, não aqueles papos que ficam pregando de “depurar menos, etc”, como se depurar agora fosse “coisa do diabo”, pois depura menos sim mas por outro lado gasta-se mais tempo com testes. Do contrário, se durante o desenvolvimento o time não passa por problemas significativos a qual o TDD procura resolver, então pode ser um gasto sem necessidade.

Enfim, tudo bem se o time vê retorno e todos ficam satisfeitos trabalhando assim. Particularmente acho extremamente chato trabalhar orientado a testes, muito mecanizado buscando resolver problemas que poderiam não existir ou que são naturalmente resolvidos de forma humanizada, com bom entrosamento entre as partes envolvidas, onde os frutos de código confiável por exemplo acabam acontecendo naturalmente.

E só para ficar claro, não dispenso testes (funcionais) pós desenvolvimento, para dar garantia do que o que está sendo alterado não vá impactar outra coisa a qual não estamos tendo a atenção.

[quote=Júlio Murta]Olá!

No começo do ultimo mês de maio tive a oportunidade de desenvolver um software “do zero”. Desta forma, fui responsável pela coleta de requisitos, modelagem, programação e tudo o mais. O software foi desenvolvido para a plataforma web utilizando a arquitetura em camadas. Sendo assim, eu tenho um projeto Dal (Data Access Layer), outro Bll (Business Logic Layer), outro Dto (Data Transfer Object) e, claro, o projeto web responsável pela UI. Acredito que eu tenha, pelo menos o básico, dos conceitos de OO bem sólidos em minha mente e que consegui aplicá-los neste projeto.

O software não consiste em nada mais que cadastros, consultas e relatórios. Inicialmente estavam previstom três módulos, e agora já tenho cinco módulos completos. É o típico projeto em que os requisitos mudam a todo momento e incrementos e adaptações são sempre necessários. Eu não estou com grandes problemas para customizá-lo ou estendê-lo, embora às vezes algo relativamente simples demore um pouco para fazer.

Pelo fato de sempre estar atendendo demandas rápidas dos usuários, sinto que a qualidade do código-fonte deste software tem se degradado. E temo que futuramente ocorram tantas mudanças que tornem o código ilegível.

Eu tenho consciência que a qualidade do código-fonte é importante, tanto para mim quanto para a equipe, e que um trabalho de refatoração será necessário. Eu até já comecei a escrita de uma segunda versão do software focando na legibilidade do código, mas gostaria de evitar agora os mesmos erros do passado. Portanto peço para todos que me ajudem com dicas, materiais, metodologias, etc… Em resumo, qualquer coisa que me ensine a escrever um software que resista às mudanças e ao tempo.

[]'s[/quote]
Na maioria dos casos é mais a experiência mesmo, o ideal é sempre ter alguém mais experiente na equipe. Se não for possível tentar se espelhar em exemplos que sejam respeitáveis, na dúvida expor o problema na prática.

O básico é sempre pensar na manutenção, não em sair fazendo por ter que entregar o mais rápido possível, não acostume mal o cliente. Código burocrático também pode atrapalhar a manutenção, como por exemplo citou DTOs, nem sempre precisa usar. “BLL” e “DAL”, dependendo do caso podem ser uma coisa só, se estiver usando Hibernate por exemplo.