Cinco citações de programação explicadas famosas



Para se tornar um programador é se inscrever em um treinamento ao longo da vida. O fluxo de novos - novos recursos, novas linguagens, novas ferramentas, novas estruturas - nunca fica seco. Mas, ao mesmo tempo, a programação é uma esfera, surpreendentemente fiel às tradições, onde tudo se baseia em princípios testados pelo tempo. Introduzimos programação orientada a objetos, soluções modernas de hardware, inteligência artificial, no entanto, apesar de todas essas mudanças, muitos dos axiomas que foram formulados na geração passada acabam sendo verdadeiros hoje.

Dediquei este artigo a algumas das minhas frases favoritas sobre programação. O único critério pelo qual fiz a seleção foi o requisito de que a cotação fosse igual a pelo menos vinte anos. Porque são apenas as tecnologias obsoletas que rapidamente se tornam inutilizáveis, enquanto os antigos mandamentos de nossos programadores ancestrais permanecem relevantes há muito tempo.

1. Indirectividade


“Todos os problemas de programação são resolvidos criando um nível adicional de indireção” - David Willer

Aqui está uma citação do livro Computer Science Theory and Application, que todo mundo gosta de repetir e poucas pessoas gostam de explicar. No entanto, essa é uma das minhas verdades de programação favoritas - revela adequadamente a própria essência da programação.

A maneira mais fácil de entender o sentido indireto é imaginar camadas. Bem, por exemplo, imagine que você tenha um pequeno projeto no qual precisa colocar o componente A dentro do componente B:



Ambos os componentes são padronizados, portanto, desmontá-los em componentes e alterar o princípio de operação não funcionarão. Você pode criar um componente complementar separado ( PlugTwoProngVariant), mas isso é muito trabalhoso e duplicação desnecessária. Existe uma solução melhor: adicione uma camada adaptadora entre esses dois componentes que interaja com sucesso com os dois e sirva como um intermediário entre eles.

Com tudo isso, se o indireto fosse esgotado pela adição de camadas adicionais entre componentes que não seriam acoplados de outra forma, seria, obviamente, útil, mas com aplicação muito limitada. Mas a própria idéia de resolver problemas alterando o ambiente das áreas problemáticas permeia toda a programação de cima para baixo. Você o encontra ao tentar ajustar um novo modelo de dados à interface antiga. Você o encontra ao tentar anexar um aplicativo com código legado ao back-end de um novo serviço da web. Você o encontra quando precisa adicionar várias novas funções de alto nível, como log e armazenamento em cache, ou coordenar o trabalho de vários serviços de alto nível, como enviar mensagens e realizar transações.No topo desta pirâmide, você chega a direções refinadas, como o aprendizado de máquina (se não conseguir escrever seu próprio comportamento, adicione outra camada de código que resolverá esse problema para você).

Muitos dirão que o objetivo da programação é escrever instruções claras em uma linguagem que até o computador mais idiota possa entender . Mas a citação de David Wheeler oferece uma visão mais profunda da questão. Ser um bom programador significa subir a escada do indireção, buscando as soluções mais comuns.

Uma cotação de bônus em

Indirectness é uma ferramenta poderosa, mas você precisa pagar pela complexidade. As pessoas raramente citam a declaração imediatamente após a famosa citação:

"Isso geralmente cria um novo problema." - David Wheeler.

É graças a essa verdade que os programadores permanecem no mercado há muito tempo.

2. Sobre simplicidade


"Simplicidade é um pré-requisito para a confiabilidade" - Edsger Dijkstra

Não faltam programadores sábios que nos alertam contra a complicação de código sem necessidade urgente. Mas poucos conseguiram mostrar tão claramente qual é a complexidade para nós, como pioneiros em ciência da computação, Edsger Dijkstra .

Este é o ponto: você faz uma escolha em favor da simplicidade, não apenas pelo desejo de tornar o futuro agradável para as pessoas. E não porque você assume a capacidade de reutilizar esse código no futuro. E não porque você deseja que ele analise com mais precisão as inspeções, e não porque você deseja facilitar o processo de fazer alterações no futuro (embora tudo isso, é claro, seja uma vantagem valiosa). Você faz isso porque a simplicidade é um pré-requisito. Sem ele, você nunca terá um código confiável que possa confiar na administração de uma empresa ou no trabalho com dados.

Para assumir a posição de Dijkstra, precisamos mudar nossa compreensão do que é "bom código". Este não é necessariamente o código mais conciso, ou o mais rápido, e certamente não o mais obscuro. Bom código é o código em que você pode confiar.

Uma cotação de bônus sobre um tópico

Uma das melhores maneiras de manter o código simples é lembrar que menos é mais. Dijkstra oferece uma nova unidade de medida que sempre nos lembrará disso:

“Se queremos contar o número de linhas de código, não devemos percebê-las como escritas, mas como gastas” - Edsger Dijkstra

3. Sobre legibilidade e reescrita


“Código é mais difícil de ler do que escrever” - Joel Spolsky

À primeira vista, essa citação de Joel Spolsky , lenda da programação e cofundadora da Stack Overflow, parece razoável, mas enganosamente superficial. Sim, os fragmentos de código são ricos em informações, compactados demais ou cansativamente longos. E isso se aplica não apenas ao que outras pessoas escreveram. Se você olhar para o seu próprio trabalho do ano passado, precisará de algum tempo para recriar a lógica que você conhecia de uma vez para a outra.

Mas a observação de Spolsky se desdobra em algo interessante. O perigo de um código difícil de ler não é apenas as consequências mais óbvias (é difícil corrigi-lo e melhorá-lo). Há outro grande perigo: o código difícil de ler parece pior do que realmente é. De fato, entender o código de outra pessoa pode parecer uma tarefa tão esmagadora que você ficará tentado a fazer o que Spolsky chama de o mais grosseiro de todos os erros - para reescrever tudo novamente.

Não estou dizendo que a arquitetura do sistema nunca se beneficie dessas reescritas. Claro, acontece que vence. Mas uma melhoria desse tipo é cara. Em tudo o que diz respeito a testar e corrigir bugs - e esses são dois componentes do desenvolvimento que levam mais tempo do que escrever o próprio código - você volta à posição inicial. Reescrever parece tentador porque se encaixa em um dos equívocos mais comuns dos desenvolvedores - a tendência de subestimar os custos de mão-de-obra de coisas conceitualmente simples. É por isso que 50% do tempo é gasto nos 5% finais do projeto. Tarefas elementares podem ser surpreendentemente demoradas! E a solução para um problema que já foi resolvido no passado sempre parece simples.

Bem, se você reescrever tudo do zero para trazer o código à perfeição, não deve ser, então quais são as alternativas mais bem-sucedidas? Resposta: envolva cada desenvolvedor no processo de refatoração fragmentada contínua . Portanto, seu código está sendo aprimorado constantemente, devido a uma cadeia de pequenas alterações - um benefício real com riscos mínimos. A legibilidade pode ser melhorada ao longo do caminho.

Citação de bônus ao tópico

Se você ainda duvida da importância da legibilidade, Martin Fowler ajudará a analisar o problema de maneira mais ampla:

“Qualquer idiota pode escrever um código que os computadores possam entender. Bons programadores escrevem código que as pessoas podem entender. ”- Martin Fowler

Em outras palavras, a tarefa do programador é emitir não apenas código funcional, mas código com lógica interna.

4. Sobre repetições


“Não repita. Cada conhecimento deve ter uma representação única, inequívoca e confiável no sistema ”- Andy Hunt e David Thomas

Todo programador que se preze sabe que muitos problemas estão na repetição. Se você escrever a mesma coisa em vários lugares, terá que gastar mais esforço testando e corrigindo bugs. Pior, você cria as condições para discrepâncias; por exemplo, um pedaço de código pode ser atualizado posteriormente e outros procedimentos relacionados podem não estar em conformidade. Um programa divergente é um programa que não pode ser confiável, e um programa que não pode ser confiável não pode ser considerado uma solução viável.



Esse bug pode ser evitado com o métodoGetTeamUniform()

, mas as repetições causam estragos não apenas no código. Esta versão do conhecido princípio DRY (não se repita) interpreta o princípio de eliminar duplicatas amplamente, cobrindo outros locais onde as repetições podem acontecer. Agora, a conversa não é mais sobre duplicatas no código - estamos falando de repetições em todo o sistema. E os sistemas codificam o conhecimento em vários formatos. Em particular, são eles:

  • Operadores
  • Comentários do código
  • Documentação para desenvolvedores ou clientes
  • Esquemas de dados (por exemplo, tabelas de banco de dados)
  • Outras especificações - planos de teste, documentos de organização de processos, regras de montagem

Todos esses grupos podem se sobrepor ao conteúdo. E quando isso acontece, existe o risco de que eles comecem a transmitir versões diferentes de uma realidade. Digamos o que fazer se a documentação descrever um modelo de trabalho e o aplicativo em si seguir outro. O que, neste caso, é considerado o detentor da verdade? Mas e se as tabelas no banco de dados não corresponderem ao modelo de dados do código? Ou se os comentários do código descrevem uma operação ou algoritmo que é fundamentalmente diferente da implementação real? Cada sistema precisa de uma representação única e confiável, na qual repousa todo o resto.

A propósito, não se deve pensar que os conflitos entre os candidatos à verdade ocorrem apenas em pequenos projetos ou são o resultado de um código de baixa qualidade. Um dos melhores exemplos que apareceu à vista é a batalha entre XHTML e HTML5. Um lado afirmou que as especificações - esta é a versão correta oficial, e os navegadores devem se adaptar a ela. Outro campo argumentou que era o comportamento dos navegadores que deveria ser considerado o padrão de fato - afinal, é assim que os designers imaginam tudo quando escrevem páginas da web. Por fim, a versão da verdade promovida pelos navegadores venceu . Desde então, o HTML5 é o que os navegadores realmente fazem, incluindo atalhos e erros válidos.

Citação de bônus no tópico.

A possibilidade de que o código e os comentários entrem em conflito entre si gerou discussões animadas: o que mais há com os comentários - bons ou ruins? Os defensores da programação extrema os tratam com total desconfiança.

“O código nunca mente, mas isso acontece com comentários” - Ron Jeffries

5. Sobre problemas complexos


“Na ciência da computação, existem apenas dois problemas complexos - invalidar o cache e criar nomes” - Phil Carleton

Aparentemente, essa citação parece ser apenas uma piada de programador, engraçada, mas não se destacando das outras. Todos podem sentir o contraste entre algo que soa como uma tarefa assustadora (invalidar um cache) e algo que soa como um verdadeiro absurdo (inventar nomes). Qualquer programador matou pelo menos uma vez horas inteiras por um problema ridiculamente pequeno - dois parâmetros, colocados na ordem errada, uma variável que está em algum lugar com letra maiúscula e em algum lugar não (obrigado, JavaScript!). Enquanto as pessoas precisam trabalhar com computadores para atingir seus objetivos, a programação sempre será uma mistura de planejamento de alto nível do sistema e erros estúpidos.

Mas se olharmos mais de perto as palavras de Phil Cardboard, encontraremos aqui mais espaço para reflexão. É difícil inventar nomes, não apenas por causa das pequenas dores de cabeça que um programador tem, toda a sua vida fica louca. O ponto aqui é que os nomes são uma das facetas da principal tarefa do programador, o design do programa. Em outras palavras, como é geralmente escrito um código claro, limpo e consistente?

Existem muitas variedades de nomes ruins. Todos nós conhecemos variáveis ​​nomeadas com base nos tipos de dados ( myString, obj), abreviações ( pcou seja, catálogo de produtos), alguns detalhes insignificantes da implementação ( swappable_name, formUserInput) ou até mesmo sem nome ( ret_value,tempArray) É fácil cair em uma armadilha e nomear uma variável com base no que você está fazendo com ela agora, e não no conteúdo. E com os valores dos tipos de dados lógicos, o problema é: o que significa progress- que o progresso já começou, que você precisa exibir informações sobre o progresso na interface ou algo mais em geral?



Fonte: CommitStrip.com

Transferir
«results_tmp_2? ?.. , ? !» — «, … , results_tmp_2. »

Mas nomes de variáveis ​​são apenas o começo. Quando você começa a criar nomes para classes, surge a questão de como dividir o código em partes independentes. Os nomes dos membros públicos determinam qual será a apresentação da interface através da qual diferentes partes do aplicativo irão interagir entre si. Ao atribuir um nome a um pedaço de código, você não está apenas descrevendo o que ele pode fazer - você está definindo o que ele fará.

Citação de bônus no tópico.
« – , » —

All Articles