Se o seu código não está claro de se ler, isto significa que a resolução do problema também não está clara na sua mente. Outro sinal importante que demonstra qualidade em um código é quando você não somente consegue escalar uma aplicação adicionando novas features, mas principalmente quando consegue remover e modificar features com facilidade.
Há uma enorme diferença entre engenharia e engenhoca e o problema é que você pode não perceber a diferença no curto prazo. Inclusive, no início do projeto, a versão engenhoca (ainda não descoberta como tal), pode parecer melhor que a versão engenharia. Ela somente se revela uma engenhoca, quando para contornar problemas simples, você precisa dar voltas e voltas, gerando mais trabalho, bugs e problemas de segurança do que uma solução inicialmente simples e sem mistérios.
Seis sinais claros de que algo pode se tornar uma engenhoca ao invés de uma engenharia:
Uma boa administração e uma boa liderança são coisas completamente diferentes. Você não administra pessoas, você administra apenas empresas. Pessoas você lidera.
É difícil concorrer com alguém que esteja fazendo um trabalho realmente apaixonado. Uma única pessoa apaixonada pelo que faz pode criar soluções que concorram com empresas enormes.
Então empresas, eu suplico, deem motivos para os seus desenvolvedores ficarem apaixonados pelo que estão criando. Não façam a gestão do medo, pois no curto prazo isto funciona, mas em seguida eles irão procurar segurança... e esta segurança está fora de sua empresa.
Você faz a comida na cozinha, mas come ela na mesa da sala, correto? Bom, você pode até comer na cozinha e aproveitar para beber diretamente da garrafa, pois neste contexto funciona, mas num contexto de um restaurante, você não vai pedir para os clientes comerem na cozinha ou beberem da garrafa.
Apesar de muita gente entender o conceito de separar responsabilidades, principalmente quando se trata MVC, não possuem a disciplina necessária para respeitar. Estas pessoas acabam gerenciando um restaurante onde os clientes comem na cozinha e bebem diretamente da garrafa, porque está mais na mão, mais prático, é como por exemplo, colocar tudo no controller.
No design de MVC, entenda que a View é o cardápio, o Controller é o garçom e o Model é o chef. A View apresenta os pratos disponíveis, o Controller leva qual prato deve ser feito ao Model e ele o prepara, pois é o único que possui a receita e sabe fazer.
Todo bug é uma surpresa. Em alguns casos, parece que o desenvolvedor não percebe que está plantando surpresas ou até mesmo gosta de plantar surpresas para reduzir a quantidade de código que irá digitar.
Há uma grande diferença entre "não teremos problema, pois não consigo imaginar o que pode dar de errado..." de algo como "eu consigo sim imaginar todas as variáveis envolvidas no presente e no futuro e não vai dar errado".
Dois pontos bem simples, na minha visão:
Como bônus, a quantidade de vezes que você já tomou uma rasteira das suas próprias implementações e aprendeu uma lição disto ajuda bastante.
No mínimo, Domain-driven Design do Eric Evans para você entender os layers da aplicação e suas responsabilidades (assim como os órgãos do corpo humano) e o Refactoring do Martin Fowler para você ter o poder de evoluir organicamente uma aplicação.
Para frases como "O quão difícil deve ser adicionar isso!?" não há problema algum, mas lembre-se, escrever novas linhas de código raramente é o maior custo... é o problema de compreensão (e da não compreensão) de todos membros da equipe, da comunicação entre todas as áreas envolvidas, das reuniões, dos emails, da manutenção e da interpretação do seu cliente sobre uma nova escolha que ele deve fazer.
Este tipo de desenvolvedor irá commitar lixo não reciclável. Não há problema algum em commitar lixo, o problema é quando ele não é reciclável (refatorável). Não me entenda errado, geralmente os desenvolvedores cowboy são ótimas pessoas e possuem muita capacidade para escrever código, porém sua ansiedade em terminar o trabalho da forma mais veloz que conseguir e sua falta de disciplina em respeitar padrões irá gerar um código que dificilmente irá evoluir sem dores extremas.
O desenvolvedor cowboy pensa da seguinte forma:
Colocar features novas sem investir também em refatoração é como colocar banco de couro em um carro antigo que só dá manutenção.
Você publicaria um artigo sem fazer a revisão? Ou seja, a primeira versão é a que vai ficar para sempre? É engraçado, pois quando se trata de texto é inaceitável. Você sabe que se ler o texto mais para frente, com um conhecimento maior sobre o assunto que está desenvolvendo, você irá lapidar, reordenar e melhorar muito o resultado.
Então deixar textos sem reavaliações é inaceitável, correto? Bom, você não tem noção como isto é comum quando se trata de código. Pelo fato das pessoas ainda não entenderem que esta mesma dinâmica se aplica a desenvolvimento, elas não se organizam para incluir isto no processo, muito menos no planejamento de recursos, elas sabem apenas adicionar novas features. Já presenciei diversas vezes injeção de recursos em features que ninguém iria utilizar, do que refatorar partes do core business que criariam um salto nos resultados e velocidade de produção. Mas convenhamos, novas features parece sempre ser mais excitante para todo mundo.
Não se esqueça que um código, diferente de um artigo, é algo vivo, com comportamento, saúde e idade. É necessário cuidar da saúde do seu código sempre que puder para não pagar um preço ainda mais caro no futuro.
Depende muito se você está tentando agradar um público varejo ou segmentado, porém quando se trata de software, considero um erro tentar compensar a falta de qualidade com quantidade. Softwares são criados para solucionar problemas, disponibilize uma quantidade enorme de soluções para o seu usuário e você criou mais um problema para ele. Principalmente quando todas estas soluções são mal pensadas e mal acabadas.
Corte features, mas não corte qualidade. Se a idéia principal do projeto é do interesse dos seus usuários, o projeto irá evoluir com o passar do tempo e você irá chegar em todas as features desejadas de uma forma mais sustentável, madura e muito mais alinhada com o usuário. Até porque, 80% dos usuários utilizarão somente 20% das features, então cuidado com o signal-to-noise ratio da sua solução.
Alguns desenvolvedores estão ficando mal acostumados e até fissurados por facilidades ao programar, o que acaba gerando muitas vezes um software de qualidade questionável. Caso eles estejam se preocupando mais com eles e a quantidade de código que precisarão escrever do que com o produto que estão criando, tome cuidado.
Esta vontade de otimização de trabalho poderá gerar um resultado catastrófico na arquitetura de um software, trazendo acoplamentos difíceis de separar e expondo detalhes de implementação em partes do código que deveriam apenas controlar o fluxo dos dados.
Agora para piorar, este desenvolvedor que está supostamente correndo rápido no seu trabalho irá reduzir a velocidade de todos os outros membros da equipe caso estes tenham que trabalhar no mesmo código.
Há algo certeiro que pude perceber sobre o assunto: caso você se encontre utilizando 10% do framework e 90% de código/design customizado, é um sinal que você criou um grande débito técnico para o seu projeto, fora que a escolha do framework foi feita utilizando mais a emoção do que a razão.
O quanto é preciso conhecer das partes internas do seu controle remoto para você conseguir apertar o botão e ligar sua TV? Ou o quanto precisa conhecer os detalhes de engenharia do Google Maps para conseguir utilizar a API deles? Quase nada, correto? Esta é a maravilha do contexto delimitado (bounded context) e desacoplamento.
O software que você está construíndo também precisa ter o contexto delimitado entre suas funções, APIs e camadas para que, quanto menos contexto você precisar manter no ceu cérebro ao mesmo tempo, mais compreensão e clareza você terá nas implementações futuras. Alterações e refatorações irão acontecer com maior velocidade, pois você não terá receio de uma funcionalidade pisar no pé da outra, pois o contexto do que cada uma faz está delimitado.
Meu pai me ensinou a ter criatividade... e agora eu consigo construir minha própria sorte.
Minha mãe me ensinou que eu devo sempre fazer a tarefa antes de poder brincar lá fora... e agora eu tenho um senso de responsabilidade altíssimo.
Meu irmão me ensinou a ser uma pessoa decente... e agora eu faço o que é correto mesmo quando ninguém está olhando.
Obrigado família!