Como treinar-se para evitar escrever código "inteligente"? [fechadas]


75

Você conhece esse sentimento quando só precisa mostrar esse novo truque com Expressions ou generalizar três procedimentos diferentes? Isso não precisa estar na escala do Architecture Astronaut e, de fato, pode ser útil, mas não posso deixar de notar que outra pessoa implementaria a mesma classe ou pacote de uma maneira mais clara, direta (e às vezes chata).

Percebi que costumo criar programas solucionando o problema , algumas vezes deliberadamente e outras por tédio. Em ambos os casos, geralmente acredito honestamente que minha solução é clara e elegante, até que eu veja evidências em contrário, mas geralmente é tarde demais. Há também uma parte de mim que prefere suposições não documentadas à duplicação de código e inteligência à simplicidade.

O que posso fazer para resistir ao desejo de escrever um código “inteligente” e quando a campainha deve tocar dizendo que estou fazendo errado ?

O problema está aumentando ainda mais, pois agora estou trabalhando com uma equipe de desenvolvedores experientes e, às vezes, minhas tentativas de escrever código inteligente parecem tolas até para mim mesmo depois que o tempo dissipa a ilusão de elegância.


5
ligeiramente fora do tópico, mas thedailywtf.com/Articles/…

@ Joe: isso é muito sobre o tema, obrigado! Eu li o artigo, mas é um prazer redescobri-lo agora.
Dan

33
Depure um monte de código inteligente ... isso deve funcionar.
Dan Olson

@ Joe, o link do banco de dados de bancos de dados nesse artigo é de morrer.
jnewman

Resposta curta: o código mais curto e mais simples vence. Elimine a duplicação, mas não adicione camadas "apenas porque". A refatoração de Fowler pode fornecer algumas dicas.
kevin Cline

Respostas:


54

O problema está aumentando ainda mais, pois agora estou trabalhando com uma equipe de desenvolvedores experientes e, às vezes, minhas tentativas de escrever código inteligente parecem tolas até para mim mesmo depois que o tempo dissipa a ilusão de elegância.

Sua solução está aqui. Presumo que "experiente" neste contexto signifique "mais experiente que você". No mínimo, você os respeita claramente. Esta é uma oportunidade valiosa de aprendizado - supondo que seu ego possa sofrer. (Coisas irritantes, egos. Pena que precisamos deles.)

Você tem análises de código com essas pessoas? Nesse caso, se eles ainda não o estão fazendo, peça-lhes explicitamente que o chamem de besteira. Mencione que você notou uma tendência em projetar demais, usar uma britadeira pneumática de ponta meticulosamente projetada (de preferência empunhada por algum tipo de andróide de trabalhador de estrada automatizado) quando um simples martelo de garra seria mais que suficiente .

Você pode frequentemente se contorcer no seu lugar enquanto seu rosto fica vermelho durante as revisões de código. Suportar isso. Você está aprendendo.

Então, depois de ter algumas dessas informações, preste atenção nos momentos em que você suspeita que esteja possivelmente projetando demais. Quando esses momentos chegarem, pergunte-se: "Se alguém me chamar sobre isso durante a revisão de código, posso defender minha solução como a melhor disponível? Ou há uma solução mais simples que estou abandonando?"

Às vezes, a revisão por pares é a melhor maneira de dar uma boa olhada no seu próprio trabalho.


Obrigado por uma resposta muito boa. Não, não temos revisões de código, principalmente porque o projeto é grande e os recursos do cliente são muito limitados. Mas acho que posso me testar perguntando "posso defender minha solução como a melhor disponível" no final de cada dia.
Dan

7
Não há revisões de código? Urk. Eu escreveria algo totalmente honesto e horrorizado, mas também trabalhei nesse ambiente. Eles consomem tempo e são meio que um saco para todo mundo, mas são realmente valiosos tanto para o projeto em questão quanto para o seu próprio desenvolvimento pessoal. Se o tópico "Devemos estar fazendo revisões de código?" sempre que surgir, verifique se você está deprimido como "Inferno, sim!" E se eles não forem cumpridos com seus próprios prazos, você pode pedir aos colegas de trabalho que você respeita que dêem trabalho, que você não tem certeza sobre uma lista informal de revisão de código.
BlairHippo

1
Bem, o projeto é uma espécie de startup e, devido a alguns erros de planejamento, também no lado do cliente, chegamos à situação em que realmente precisamos entregar rapidamente, ou então não vale a pena o esforço. Acabei de falar com nosso PM e ele confirmou que o prazo agressivo é a única razão pela qual não fazemos revisões de código, pelo menos agora. Se a inicialização for bem-sucedida e as restrições de tempo ficarem mais relaxadas, poderemos fazer as revisões no futuro.
Dan

2
Oh meu. Parece emocionante - com todas as boas e más conotações que a palavra carrega. :-) Boa sorte, meu caro; espero que você esteja no começo de algo ótimo.
BlairHippo

8
@BlairHippo: Acabei de seguir seu conselho, me acalmei e gentilmente perguntei ao colega que apontou o problema introduzido pelas minhas alterações para fazer revisões informais comigo, e ele concordou. Isso também ajudou a remover certo constrangimento de nossa conversa (como em "você escreve um código complexo e eu preciso corrigi-lo .."). Obrigado!
Dan

20

A melhor coisa a fazer é ter em mente a máxima de Brian Kernighan:

“A depuração é duas vezes mais difícil do que escrever o código em primeiro lugar. Portanto, se você escrever o código da maneira mais inteligente possível, por definição, você não é inteligente o suficiente para depurá-lo. ”


1
Concordo plenamente com a citação, mas a questão é como superar a tentação de ser o garoto esperto ? Você pode ser instruído a não tomar sorvete quando estiver doente, mas às vezes isso não ajuda.
Dan

13
+1 para uma máxima que todo macaco de código deve saber de cor, mas -1 por não oferecer ao OP qualquer insight sobre como aplicá-lo ao seu próprio trabalho. Portanto, tudo se compara a nenhum clique na seta.
BlairHippo

2
Ótima citação, mas não é realmente uma resposta para a pergunta do OP.
11137 Jim G.

5
Olá Daniel, estamos procurando muito mais que uma citação: o site é útil apenas quando perguntas são combinadas com respostas longas e ponderadas, cheias de experiências, fatos e referências. Existe algo mais a partir da sua própria experiência, você pode adicionar?

2
-1: Não responde nem um pouco à pergunta do OP.
Thomas Eding

15

Geralmente, existem pelo menos três soluções para problemas de software de qualquer significado: a maneira óbvia, uma maneira complexa não óbvia (inteligente) e uma maneira simples não óbvia (elegante). Uma citação sobre autores é aplicável aqui:

Coloque tudo o que lhe vier à cabeça e então você é um escritor. Mas um autor é aquele que pode julgar o valor de suas próprias coisas, sem piedade, e destruir a maior parte delas. - Colette

Você não poderá escrever um código elegante até poder julgar o valor do seu próprio código, sem piedade, e destruir a maior parte. Se você julga um código elegante pelo resultado final, parece enganosamente fácil, mas exige lentidão, passando por vários rascunhos, buscando o conselho de outras pessoas e excluindo o que não aparece na página. Isso significa que, mesmo que seu código esteja funcionando perfeitamente, você se pergunta ou a um colega por que algo não parece certo até que você esteja satisfeito com a resposta. Talvez pareça muito longo ou repetitivo, ou você sinta que o compilador deveria ter sido capaz de detectar um certo tipo de bug. A maioria dos programadores com um pouco de experiência pode reconhecer códigos deselegantes facilmente. O truque é descobrir o porquê .

Essa é a maneira metódica de escrever código mais elegante. Também frequentemente requer um flash de insight que ajuda a analisar um problema de uma nova maneira. Isso é mais difícil de obter, mas ajuda a diminuir a velocidade e pensar em um problema antes de mergulhar na codificação. Quando você encontrar uma boa solução, procure uma melhor. Ler outro código ajuda. Ter aulas ou ler livros sobre práticas recomendadas ajuda. Aprender outros paradigmas de programação ajuda. Pedir conselhos de colegas cujo código você admira ajuda.


3
Isso me lembra uma citação de um antigo matemático: "Para todo problema, existe uma solução simples, elegante e errada".
Joris Timmermans

9

Eu acrescentaria às respostas existentes, desenvolveria de maneira TDD, para que você primeiro escreva testes sobre o que seu código deve fazer e depois implemente para tornar seus testes ecológicos. Dessa forma, você estará cumprindo apenas os requisitos que os testes estão impondo. Como você estará escrevendo o teste, é uma boa maneira de desenvolver uma abordagem autodisciplinada.


Eu definitivamente tento impor isso a mim mesma sempre que há tempo.
jnewman

Escrever testes posteriormente também é uma boa maneira de detectar grandes erros no seu código. De alguma forma, é autoavaliação. Mas TDD é claramente a melhor abordagem se você está começando do zero.
vanna

6

Ao trabalhar para uma equipe grande e dinâmica, que abrange muitos conjuntos de habilidades e anos diferentes, o desenvolvimento tem uma progressão natural para ser "embotado" até o nível mais baixo do membro da equipe mais conservador ou com deficiência intelectual, atual ou histórica.

Isso pode não ser necessariamente uma coisa ruim, porque o código inteligente pode ser mais difícil de depurar, mais difícil de transmitir em uma especificação técnica e levar mais tempo para escrever, diminuindo o tempo de desenvolvimento.

Há momentos em que o código inteligente é importante, como quando o código inteligente fornece ganhos de eficiência e desempenho posteriormente no ciclo de maturidade do software, quando o desempenho se torna um requisito.

O código inteligente também tem como transmitir um código mais rápido de desenvolver e mais legível e compreensível para uma equipe que pode não estar exposta a um novo recurso de idioma ou chamada de biblioteca. Por exemplo, quando fui apresentado ao Linq pela primeira vez por um desenvolvedor júnior, senti um nojo imediato por ser desnecessário, difícil de depurar, tolo e "inteligente". Depois de brincar com ele e descobrir o quão úteis e poderosas as consultas do Linq podem ser, investi tempo para aprendê-lo e meu código DAL nunca foi tão limpo e legível, além de mais fácil de depurar e estender.

Lamento não ter uma mente aberta antes e gostaria de não ter sido tão duro com um desenvolvedor júnior tão "inteligente".

O que quero dizer é que o código "inteligente" DEVE suspeitar, mas não devemos fazer uma cruzada contra ele, pois pode sufocar a criatividade e a inovação.

EDIT: Acabei de perceber que não respondi completamente à sua pergunta. Se você tem capacidade no seu projeto para escrever com muita facilidade códigos inteligentes, talvez a equipe deva adotar padrões de codificação mais rígidos para seguir um modelo e estilo uniforme e distinto. Isso ajudará a traçar as linhas da sua caixa de areia, para que você não entre na rua correndo atrás de uma bola.


6

Se 20% (o seu% pode variar) ou mais linhas adicionadas precisam ser documentação - é hora de voltar atrás e repensar .

Eu realmente acho que você deve se esforçar para ser inteligente, é um efeito colateral natural de se tornar mais eficiente. Dar a si mesmo uma orientação geral como% de comentários necessários para deixar claro é uma boa maneira de se forçar a se afastar e avaliar se o uso dessa coisa nova que você aprendeu é uma escolha sábia ou apenas uma maneira de mostrar seu novo brinquedo.


3
Costumo considerar a documentação / comentários como um fracasso. Quando você precisa documentar / comentar algo, significa que, em primeiro lugar, seu código não está claro. Infelizmente, esse é um objetivo irreal e precisamos documentar em algum momento. Lembre-se de que essa parte do código deve ser reduzida a um valor mínimo.
### deadalnix #

@deadalnix: Não é um ponto ruim. Eu suspeito que meu% seria maior do que a maioria, porque eu normalmente codifico em uma linguagem assembly morta e com macros pesados. Mais difícil de ler e todos os novos contratados precisam aprender o idioma, mais comentários são necessários como resultado.
DKnight

2
@deadalnix - documentação para explicar como é um sinal de que seu código não é claro. Documentação para explicar o porquê é muito necessária. Eu já vi muitos pedaços de código para entender o que eles fizeram, mas não por que eles decidiram fazê-lo dessa maneira não intuitiva. Isso torna muito difícil de manter.
HLGEM

@HLGEM Isso é discutível. A falta de clareza do código pode vir de libs / API mal projetadas, de falta de clareza dentro da própria concepção como uma má separação de preocupações. Como vivemos no mundo real e nossas capacidades são finitas, precisamos de documentação definitiva, mas cada vez que precisamos, significa que alguém escreveu um código imperfeito. Nenhuma documentação não é algo que você deve fazer - nem pense nisso, mas algo que você precisa pensar o tempo todo para continuar melhorando na direção certa.
Deadalnix

@deadalnix - código perfeito nunca é uma solução prática no mundo real.
Jeffo

4

Não resisto a tentar algo inteligente.

Então, eu faço isso em um projeto de brinquedo, no meu tempo livre, em casa.

Quando a novidade desaparece - problema resolvido.


3

Acredito que uma maneira de descobrir se seu código é "inteligente" demais é dar um passo atrás e se perguntar o seguinte:

Se eu desse uma impressão deste código a alguém que nunca trabalhou nesse projeto / código, eles poderiam lê-lo e descrever de volta para mim o que a função faz (depois de fornecer a eles um breve contexto)? Se não, quanta explicação eu teria que fazer? Como eu explicaria isso para alguém que toma o CS101?

Se você precisar percorrer alguém em todas as linhas ou na maioria das linhas de um método ou classe, provavelmente é muito inteligente. Se você precisar explicar as construções de linguagem (LINQ, por exemplo) para alguém que não esteja familiarizado com isso, provavelmente isso é bom. Se você precisar olhar para uma linha e pensar um pouco antes de poder explicá-la, seu código precisará ser refatorado.


Eu ouvi isso chamado "Ducking de borracha" quando aplicado à solução de problemas; quando estiver perplexo, tente explicar o problema para alguém que não sabe nada sobre ele (como seu patinho de borracha) e veja se a solução não cai no seu colo. Eu tenho que pensar que funcionaria para isso também.
BlairHippo

2

1) Se queime antes, para que você saiba que é uma coisa ruim. Tentar depurar algo de muito tempo atrás que seja escrito de maneira inteligente é muito divertido. Eu acho que você tem isso coberto.
2) Comente seu código, explique o que você está fazendo antes de cada seção do código.
3) Se você se esforçar para explicá-lo ou sentir a necessidade de inserir um diagrama, o que você acabou de fazer é muito inteligente e provavelmente poderia ser feito de maneira mais limpa.

Soluções inteligentes para problemas podem ser fantásticas, até que você precise depurá-las ou expandi-las. Às vezes é a única solução. Se você pode descrever com precisão o que diabos faz e como faz, soluções inteligentes podem ser aceitáveis.

Normalmente, uso comentários para descrever o que estou fazendo com uma seção de código. Se parecer menos confuso, também descrevo como estou fazendo isso. Idealmente, o código deve ser direto e auto-explicativo. Mas se eu me esforçar para explicar como fiz o que acabei de fazer, é um sinal claro de que preciso dar um passo atrás e tentar novamente.


2
O truque de comentários também funciona para mim. Entre outras razões, sempre incluo um bloco de comentários acima de qualquer sub-rotina não trivial como uma espécie de verificação final de sanidade. Se eu tiver que explicar muitas vezes (ou até pedir desculpas por) seções complicadas ou obtusas de código ou parâmetros estranhos de entrada ou qualquer outra coisa, isso é um sinal de alerta para que eu precise repensar um pouco a solução.
BlairHippo

@BlairHippo HA! "verificação final da sanidade" Eu gosto disso.
Philip

2

Provavelmente, uma boa maneira de começar a escrever código simples é liberar a paixão pela esperteza em um projeto que pede esperteza . O restante da resposta é específico do .NET, mas tenho certeza de que é possível encontrar projetos de nível semelhante em qualquer outro idioma.

Existem estruturas de injeção de dependência de código aberto para trabalhar, nas quais basta pedir Expressionconhecimento de truques, há F # e uma maravilhosa variedade de tarefas pelas quais alguém pode querer tentar.

Se você gosta de matemática (e isso é independente da linguagem ), existe o Projeto Euler para você.

Por último, mas não menos importante, no mundo .NET existe o Mono Project que tem muitas áreas que precisam de atenção do desenvolvedor , algumas delas bastante complicadas. Que tal contribuir para uma ferramenta de análise de código .NET estática de código aberto ? Há algumas análises de IL envolvidas, bem como coisas de alto nível. Jb Evain sempre trabalha em algo interessante, seja a biblioteca de reflexão Cecil, Expressionsuporte ou um descompilador .NET.

Se nada se encaixar, basta iniciar sua própria estrutura de zombaria :-)


2

Você conhece esse sentimento quando só precisa mostrar esse novo truque com Expressões ou generalizar três procedimentos diferentes?

Não

Essa é uma das razões pelas quais eu sempre digo que é bom quando novos desenvolvedores são lançados em uma grande e velha bagunça de código speghetti não documentado para manter e refatorar. Isso ensinará a eles a realidade de manter código excessivamente 'inteligente' que eles não escreveram e, esperançosamente, instilará alguma empatia pelo pobre idiota que terá que depurar seu código daqui a cinco anos.


Eu acho que é mais provável que isso os frustre e pense que SEU código será muito melhor e elegante do que os noobs que escreveram ESTA bagunça. Ninguém escreve código com a intenção de dificultar a manutenção.
Sara

2

Eu acho que o tópico está bem escolhido. É "legal" escrever uma linha de Perl que faça dez mil coisas de uma só vez, mas é uma merda quando você precisa revisitá-la.

Em uma nota diferente, inteligente ou não, o código deve ser documentado. Existe uma incompatibilidade inerente de impedância entre as linguagens de programação aceitas pelo setor e os conceitos de alto nível que nós, como seres humanos, estamos acostumados em nosso pensamento. O código de auto-documentação simplesmente não é realizável - até que se torne uma linguagem natural. Mesmo o código Prolog precisa ser documentado, pois, por mais alto nível que seja, ele ainda é bastante formal.

O código imperativo de granulação fina serve para implementar planos de granulação grossa - que precisam ser documentados. Não quero ter que ler todas as 50 linhas do método quando um comentário rápido de um roteiro de 3 linhas for suficiente.

Edição posterior: Um exemplo mais eloquente é aquele que transcende os computadores. Um livro pode ser muito bem escrito, mas geralmente queremos processá-lo em diferentes níveis de abstração. Muitas vezes, um resumo do livro é suficiente, e é isso que os comentários podem oferecer ao código. É claro que o código bem abstraído pode percorrer um longo caminho para a auto-documentação, mas não pode fornecer todos os níveis de abstração.

E os comentários também podem agir como notas de rodapé de um livro, quando precisamos explicar o processo de raciocínio por trás de uma reivindicação no texto principal sem descarrilá-la.

Nesse contexto, acho que minha declaração anterior referente à linguagem natural que transcende a necessidade de comentários está incorreta. Mesmo a linguagem natural, como em um livro, pode se prestar a documentação, explicar de maneira esparsa a abstração incorporada no texto ou fornecer desvios sem atrapalhar o texto principal. Com a observação de que um código bem abstraído já pode ter sido um longo caminho para se auto-documentar.

Por último, mas não menos importante, os comentários podem ajudar o codificador a manter um alto nível de abstração. Muitas vezes, percebo que dois comentários consecutivos incluídos em uma lista de etapas não falam no mesmo nível de abstração, o que justifica imediatamente uma análise crítica do que estou fazendo com esse código.

Certos problemas transcendem a codificação e afetam a codificação como outras atividades. Os comentários podem fornecer essa ajuda para esclarecer a lógica por trás e as facetas do nosso código, e eu os acho um companheiro agradável que fala um idioma mais suave para beneficiar a pessoa por uma mudança.


1

Quão? Continue mostrando seu código para os desenvolvedores experientes. e quando você se sentir culpado por ser sophomoric e vistoso, sugá-lo e perguntar-lhes como eles fariam isso e por quê (de uma maneira sem confronto, é claro).

Editar à luz de -1:

Muitas luas atrás, eu estava na mesma situação - eu tinha um chefe que ficava encolhido toda vez que usava um ponteiro em Delphi ou o 'com construção', outro que ameaçava me demitir se eu não parasse de usar todos os meus booleanos com 0-1 e usando variáveis ​​de letra única em todos os lugares.

Eu aprendi porque perguntei o porquê e eles se deram ao trabalho de explicar porque achavam que eu poderia significar algo - LOL ....


1
Olá Mikey, estamos procurando muito mais do que uma frase: o site só é útil quando perguntas são combinadas com respostas longas e ponderadas, cheias de experiências, fatos e referências. Existe algo mais a partir da sua própria experiência, você pode adicionar?

1

Sinto a necessidade de me exibir? Não, não mais. Como eu superei isso? Como a maioria das pessoas passa por qualquer outro mau hábito ... prática consciente e deliberada de técnicas apropriadas. Você faz o suficiente para entender o valor das melhores práticas e, através do uso constante delas, desenvolverá bons hábitos.

Perceba também que, concentrando-se no software funcional, pontual e facilmente mantido, você obterá o reconhecimento que procura. Desenvolvedores experientes entrarão em contato com você e dirão "Cara, o módulo que você escreveu foi bem projetado. Eu só precisei implementar um componente para conectá-lo ao meu projeto". ao contrário de "Eu tive que refazer todo o módulo que você escreveu para usá-lo em outro componente? Você já ouviu falar de Bob Martin ou Ward Cunningham?"

TLDR: Você não está sozinho. O reconhecimento da habilidade é melhor alcançado como subproduto da solução de problemas da maneira inteligente.


0

Para mim, o código excessivamente inteligente geralmente se esforça para resolver requisitos futuros imaginários, em vez de se concentrar nos requisitos atuais. Grande armadilha!

0% de código excessivamente complicado não é uma meta alcançável. Talvez nem seja o melhor objetivo pelo qual lutar. Código muito complicado é ruim, mas você precisa tentar coisas novas para crescer como programador. Você não deve experimentá-los no código de produção, se puder evitá-lo. Ao contrário das máquinas, os humanos cometem erros.

Revisões de código ajudam. Passar anos consertando o código "inteligente" de outras pessoas ajuda. Manter o foco no que o cliente realmente precisa hoje ajuda.

Escolas e empresas contam com equipes de pessoal de limpeza e manutenção. O código também precisa de limpeza e manutenção! Sempre que possível, limpe a bagunça (especialmente a sua)! Eu acho que é o melhor que se pode fazer.


-2

Além dos bons conselhos dados até agora (revisão de código, depuração, abordagem TDD), você deve (re) ler periodicamente os (melhores livros imho) sobre boas práticas de codificação:

  • Programador pragmático
  • Código completo
  • Código Limpo

e outros, dependendo da tecnologia que você usa.


-2

Apenas lembre-se de YAGNI - Você não precisará disso .

O programador não deve adicionar funcionalidades até que seja considerado necessário ...

YAGNI é um princípio por trás da prática XP de "fazer a coisa mais simples que poderia funcionar" (DTSTTCPW). Ele deve ser usado em combinação com várias outras práticas, como refatoração contínua, teste de unidade automatizado contínuo e integração contínua. Usado sem refatoração contínua, pode levar a códigos confusos e retrabalho maciço ...

De acordo com aqueles que defendem a abordagem do YAGNI, a tentação de escrever código que não é necessário no momento, mas pode ser no futuro, tem as seguintes desvantagens:

  • O tempo gasto é gasto na adição, teste ou aprimoramento da funcionalidade necessária.
  • Os novos recursos devem ser depurados, documentados e suportados.
  • Qualquer novo recurso impõe restrições sobre o que pode ser feito no futuro; portanto, um recurso desnecessário pode impedir que os recursos necessários sejam adicionados no futuro.
  • Até que o recurso seja realmente necessário, é difícil definir completamente o que ele deve fazer e testá-lo. Se o novo recurso não for definido e testado corretamente, ele pode não funcionar corretamente, mesmo que eventualmente seja necessário.
  • Isso leva ao inchaço do código; o software se torna maior e mais complicado.
  • A menos que haja especificações e algum tipo de controle de revisão, o recurso pode não ser conhecido pelos programadores que poderiam fazer uso dele.
  • Adicionar o novo recurso pode sugerir outros novos recursos. Se esses novos recursos também forem implementados, isso poderá resultar em um efeito bola de neve no sentido da fluência ...

3
Embora isso possa ser verdade - mais detalhes tornariam essa uma resposta muito melhor.
ChrisF
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.