No livro Programador Pragmático , os escritores mencionam a programação por conceito de coincidência . Explica o que é, por que é causado, quais são os perigos que você pode encontrar e se compara a um campo de minas terrestres em uma guerra.
Você já assistiu velhos filmes de guerra em preto e branco? O soldado cansado avança cautelosamente para fora do mato. Há uma clareira pela frente: existem minas terrestres ou é seguro atravessar? Não há indicações de que seja um campo minado - sem sinais, arame farpado ou crateras. O soldado cutuca o chão à sua frente com sua baioneta e estremecimentos, esperando uma explosão. Não existe um. Então, ele prossegue meticulosamente pelo campo por um tempo, cutucando e cutucando enquanto caminha. Por fim, convencido de que o campo é seguro, ele se endireita e marcha orgulhosamente para a frente, apenas para ser despedaçado.
As sondas iniciais do soldado para minas não revelaram nada, mas isso foi apenas uma sorte. Ele foi levado a uma conclusão falsa - com resultados desastrosos.
Como desenvolvedores, também trabalhamos em campos minados. Há centenas de armadilhas esperando para nos pegar todos os dias. Lembrando a história do soldado, devemos ter cuidado em tirar conclusões falsas. Devemos evitar a programação por coincidência - confiando na sorte e em sucessos acidentais - em favor da programação deliberada ...
Mas não estou realmente satisfeito com a maneira como descrevem o problema "como superá-lo". Sim, você precisa pensar antes de escrever o código, mas como praticar isso? A única coisa que consigo pensar é adicionar recursos aos projetos de código aberto existentes, nos quais você deve ter conhecimento sobre o "o que estou fazendo agora" e o "Como os outros trechos de código estão funcionando", e isso não é aplicável. quando você está escrevendo seus próprios projetos.
EDITAR:
um resumo de suas postagens:
- Não adivinhe o seu próximo passo, prove que está correto
- Teste de unidade e refatorar o máximo possível, quando necessário
- Adicione recursos - compile - teste frequentemente
- Se você não pode explicar o código para um noob, provavelmente está programando por coincidência.
BTW, é difícil aceitar uma resposta, é realmente difícil. Todas as respostas são realmente ótimas :)
fonte
Respostas:
Você não precisa pensar no futuro, apenas seja muito claro sobre o que foi feito e muito claro sobre o que está fazendo agora.
As sub-rotinas devem dizer o que fazem, fazer o que dizem e não ter dependências ocultas. Então, alguém que os chama pode raciocinar mais facilmente sobre o que eles farão.
Evite o estado global. (Variáveis, singletons etc.) Quanto mais você precisar ter em mente para entender o que as coisas fazem, mais difícil será entender o que deve acontecer e encontrar os casos extremos.
Escreva testes de unidade. Os testes de unidade são ótimos para capturar o comportamento real do código que você acabou de escrever, em vez do comportamento ideal que você espera encontrar.
Encurte seu ciclo de edição / compilação / teste. Quando você adiciona um grande pedaço de código e faz um teste ruim, as chances são de que ele se comporte de maneira diferente do que você pensa. Então você o "corrige" com algumas mudanças aleatórias, e você tem a resposta certa no momento, mas não tem idéia de como isso realmente aconteceu. Agora você está programando por coincidência. Mas quando você adiciona 5 linhas e depois testa, as chances de você ter a resposta certa, porque funciona como você pensa que funcionam, são muito melhores. Posso dizer por experiência que 5 blocos de 10 linhas cada, testados individualmente, são um animal muito diferente de 50 linhas de código testadas ao mesmo tempo.
Refatorar impiedosamente. Muitas vezes vi um refator que tornaria meu código um pouco mais simples, mas exigia um monte de trabalho que eu não queria fazer. Depois que comecei a abordar deliberadamente esses refatores como uma prioridade, descobri que geralmente compensa em um mês. Mas observe a chave: os refatores em que me concentro são aqueles que tornam a vida cotidiana mais simples, e não aqueles que atendem a uma estética arbitrária de melhor ou mais geral. Com esses refatores, aprendi a ser muito mais cauteloso.
Nenhuma dessas coisas requer planejamento antecipado. Mas todos facilitam a compreensão do código existente e, portanto, facilitam a implementação do seu próximo pequeno pedaço de maneira deliberada.
fonte
UNION
onde eu precisavaUNION ALL
.) E assim por diante.Tudo se resume a não adivinhar . Principalmente os novos programadores fazem isso, mas vi veteranos também, porque acham que economiza tempo de pesquisa. Algo não funciona, então você adiciona a
+1
ou a-1
, altera atrue
para afalse
ou vice-versa, reordena algumas instruções, adiciona ou altera atrasos, altera prioridades de threads e outras pequenas transformações, basicamente testando permutações aleatórias até que funcione.Isso se aplica principalmente à alteração do código existente, mas também é um fator no código totalmente novo, porque ninguém realmente começa do zero. Você está sempre construindo sobre bibliotecas padrão, sistemas operacionais ou pelo menos arquiteturas de processador.
Em outras palavras, você não estará pronto até saber por que sua correção funciona. O caminho a seguir para chegar lá não importa tanto. Às vezes, até permutações aleatórias podem ser úteis para restringir um erro difícil de diagnosticar, desde que você dedique algum tempo para se perguntar: "Ok, alterar verdadeiro para falso corrigiu, mas por quê?"
fonte
O comentário mais assustador que já encontrei em um programa foi
e é assustador apenas porque reconhece que o código foi o resultado da programação por coincidência .
Para evitar a programação por coincidência, você deve explicar (a um colega de trabalho, a si mesmo ou a um pato de borracha ) exatamente o que o código faz e por que funciona. Os marcadores para a programação deliberada são principalmente ajuda para avançar em direção ao objetivo de poder explicar o código.
1 Para o contexto, esse comentário apareceu no código que lida com as alternâncias de contexto em um sistema operacional primitivo. O código já estava em produção há vários anos quando o encontrei.
fonte
Para novos programadores, a parte mais importante de superar isso é realmente entender o que estão fazendo.
Em muitas áreas, quando você não sabe fazer alguma coisa, basta tentar e errar. Tentar algo; se funcionar, ótimo, se não, tente outra coisa.
Na programação, especialmente ao usar uma linguagem que tem o conceito de comportamento indefinido (como C ou C ++), essa abordagem simplesmente não funciona, porque o sucesso não é mais uma decisão booleana. Você pode ter coisas que "meio que" funcionam, que às vezes funcionam, que funcionam para algumas entradas, mas não para outras.
Ocasionalmente, ensinei novos programadores, e a tendência de tentar digitar coisas aleatórias para ver se funciona é comum. Eles digitavam uma linha e depois se viravam para mim e perguntavam: "Funcionaria assim?" embora estivesse claro que eles não tinham absolutamente nenhuma idéia se poderia.
O argumento é que, como um novo programador, você realmente precisa explicar o que seu código faz. Você precisa aprender a ler código, não apenas escrevê-lo.
(É claro que isso também se aplica a programadores experientes, mas minha experiência aqui foi principalmente com novos iniciantes completos.)
fonte
É muito fácil codificar, testar e corrigir "na linha de corrida". Você tem alguma funcionalidade que, dada X e Y, produz Z. Mas e se X estiver corrompido e Y não estiver disponível? E se você não conseguir gerar o Z? Sempre tenha em mente o que pode dar errado e faça uma anotação para o ciclo de teste.
Mantenha suas rotinas curtas e descritivas - o melhor código requer poucos (se houver) comentários.
Nomes significativos de métodos, classes e variáveis contribuem bastante para facilitar a legibilidade.
Se você encontrar um cheiro de código, PARE. É pouco provável que esse cheiro desapareça e um pouco de esforço agora pode poupar uma enorme quantidade de sofrimento mais tarde.
Inclua testes no seu processo de desenvolvimento. Eu defenderia o uso do BDD em vez do TDD , pois obriga a descrever o que você pretende alcançar, em vez de confiar cegamente em uma série de testes que podem lhe dar uma falsa sensação de segurança.
Resista ao desejo de adicionar recursos interessantes adicionais (a menos que seja seu próprio projeto de estimação). Qualquer código extra precisa ser projetado, escrito, testado e mantido. Se não for exigido pelo cliente / empresa - você corre o risco de se tornar um grande esgotamento de seus recursos.
fonte