Aprender sem pensar é trabalho perdido; pensar sem aprender é perigoso.
Os ninjas programadores do passado usaram esses truques para aguçar a mente dos mantenedores de código.
Os gurus da revisão de código os procuram em tarefas de teste.
Os desenvolvedores novatos às vezes os usam ainda melhor do que os ninjas programadores.
Leia-os com atenção e descubra quem você é – um ninja, um novato ou talvez um revisor de código?
Ironia detectada
Muitos tentam seguir caminhos ninja. Poucos conseguem.
Faça o código o mais curto possível. Mostre o quão inteligente você é.
Deixe que recursos de linguagem sutis guiem você.
Por exemplo, dê uma olhada neste operador ternário '?'
:
//retirado de uma biblioteca javascript bem conhecida eu = eu? eu < 0? Math.max(0, len + i): i: 0;
Legal, certo? Se você escrever assim, um desenvolvedor que se deparar com essa linha e tentar entender qual é o valor de i
vai se divertir muito. Então venha até você, em busca de uma resposta.
Diga a eles que mais curto é sempre melhor. Inicie-os nos caminhos do ninja.
O Dao se esconde na falta de palavras. Somente o Dao está bem iniciado e bem concluído.
Outra maneira de codificar mais curto é usar nomes de variáveis com uma única letra em todos os lugares. Como a
, b
ou c
.
Uma pequena variável desaparece no código como um verdadeiro ninja na floresta. Ninguém conseguirá encontrá-lo usando a “pesquisa” do editor. E mesmo que alguém o faça, não conseguirá “decifrar” o que significa o nome a
ou b
.
…Mas há uma exceção. Um verdadeiro ninja nunca usará i
como contador em um loop "for"
. Em qualquer lugar, mas não aqui. Olhe ao redor, há muito mais letras exóticas. Por exemplo, x
ou y
.
Uma variável exótica como contador de loop é especialmente interessante se o corpo do loop ocupar de 1 a 2 páginas (aumente mais, se puder). Então, se alguém olhar profundamente dentro do loop, não será capaz de descobrir rapidamente que a variável chamada x
é o contador do loop.
Se as regras da equipe proíbem o uso de nomes vagos e de uma letra – encurte-os, faça abreviações.
Assim:
list
→ lst
.
userAgent
→ ua
.
browser
→ brsr
.
… etc.
Somente quem tiver uma intuição verdadeiramente boa será capaz de compreender tais nomes. Tente encurtar tudo. Somente uma pessoa digna deve ser capaz de apoiar o desenvolvimento do seu código.
A grande praça não tem cantos
O grande navio está completo pela última vez,
A grande nota é o som rarefeito,
A grande imagem não tem forma.
Ao escolher um nome, tente usar a palavra mais abstrata. Como obj
, data
, value
, item
, elem
e assim por diante.
O nome ideal para uma variável é data
. Use-o em todos os lugares que puder. Na verdade, toda variável contém dados , certo?
…Mas o que fazer se data
já foram obtidos? Experimente value
, também é universal. Afinal, uma variável eventualmente recebe um valor .
Nomeie uma variável pelo seu tipo: str
, num
…
Experimente. Um jovem iniciado pode se perguntar – esses nomes são realmente úteis para um ninja? Na verdade, eles são!
Claro, o nome da variável ainda significa alguma coisa. Diz o que está dentro da variável: uma string, um número ou outra coisa. Mas quando alguém de fora tenta entender o código, ficará surpreso ao ver que na verdade não há informação alguma! E, em última análise, não conseguirá alterar seu código bem pensado.
O tipo de valor é fácil de descobrir por depuração. Mas qual é o significado da variável? Qual string/número ele armazena?
Simplesmente não há como descobrir sem uma boa meditação!
…Mas e se não existirem mais esses nomes? Basta adicionar um número: data1, item2, elem5
…
Somente um programador verdadeiramente atento deverá ser capaz de entender seu código. Mas como verificar isso?
Uma das maneiras – use nomes de variáveis semelhantes, como date
e data
.
Misture-os onde puder.
Uma leitura rápida desse código torna-se impossível. E quando há um erro de digitação… Hummm… Ficamos muito tempo presos, hora de tomar chá.
O Tao que pode ser contado não é o Tao eterno. O nome que pode ser nomeado não é o nome eterno.
Usar nomes semelhantes para as mesmas coisas torna a vida mais interessante e mostra sua criatividade ao público.
Por exemplo, considere prefixos de função. Se uma função mostrar uma mensagem na tela – inicie-a com display…
, como displayMessage
. E então, se outra função mostrar algo diferente na tela, como um nome de usuário, inicie-a com show…
(como showName
).
Insinue que há uma diferença sutil entre essas funções, embora não haja nenhuma.
Faça um pacto com outros ninjas da equipe: se John começar a “mostrar” funções com display...
em seu código, então Peter poderá usar render..
e Ann – paint...
. Observe como o código se tornou muito mais interessante e diversificado.
…E agora o hat-trick!
Para duas funções com diferenças importantes – use o mesmo prefixo!
Por exemplo, a função printPage(page)
usará uma impressora. E a função printText(text)
colocará o texto na tela. Deixe um leitor desconhecido pensar bem sobre a função de nome semelhante printMessage
: “Onde ela coloca a mensagem? Para uma impressora ou na tela?”. Para que realmente brilhe, printMessage(message)
deve exibi-lo na nova janela!
Uma vez dividido o todo, as partes
preciso de nomes.
Já existem nomes suficientes.
É preciso saber quando parar.
Adicione uma nova variável somente quando for absolutamente necessário.
Em vez disso, reutilize os nomes existentes. Basta escrever novos valores neles.
Em uma função tente usar apenas variáveis passadas como parâmetros.
Isso tornaria muito difícil identificar o que está exatamente na variável agora . E também de onde vem. O objetivo é desenvolver a intuição e a memória de quem lê o código. Uma pessoa com intuição fraca teria que analisar o código linha por linha e rastrear as alterações em cada ramificação do código.
Uma variante avançada da abordagem é substituir secretamente (!) o valor por algo semelhante no meio de um loop ou função.
Por exemplo:
function ninjaFunction(elem) { // 20 linhas de código trabalhando com elem elem = clone(elem); // Mais 20 linhas, agora trabalhando com o clone do elem! }
Um colega programador que quiser trabalhar com elem
na segunda metade da função ficará surpreso… Somente durante a depuração, após examinar o código, ele descobrirá que está trabalhando com um clone!
Visto no código regularmente. Mortalmente eficaz mesmo contra um ninja experiente.
Coloque sublinhados _
e __
antes dos nomes das variáveis. Como _name
ou __value
. Seria ótimo se você soubesse o significado deles. Ou, melhor, adicione-os apenas por diversão, sem nenhum significado particular. Ou significados diferentes em lugares diferentes.
Você mata dois coelhos com um tiro. Primeiro, o código se torna mais longo e menos legível e, segundo, um colega desenvolvedor pode passar muito tempo tentando descobrir o que significam os sublinhados.
Um ninja inteligente coloca sublinhados em um ponto do código e os evita em outros lugares. Isso torna o código ainda mais frágil e aumenta a probabilidade de erros futuros.
Deixe que todos vejam quão magníficas são suas entidades! Nomes como superElement
, megaFrame
e niceItem
certamente esclarecerão o leitor.
Na verdade, por um lado, algo está escrito: super..
, mega..
, nice..
Mas por outro lado – isso não traz detalhes. Um leitor pode decidir procurar um significado oculto e meditar por uma ou duas horas de seu tempo de trabalho remunerado.
Quando está na luz, não consigo ver nada na escuridão.
Quando está na escuridão, consegue ver tudo na luz.
Use os mesmos nomes para variáveis dentro e fora de uma função. Tão simples. Nenhum esforço para inventar novos nomes.
deixe usuário = autenticarUsuário(); função renderização() { deixe usuário = outroValor(); ... ...muitas linhas... ... ... // <-- um programador quer trabalhar com o usuário aqui e... ... }
Um programador que entra na render
provavelmente não perceberá que há um user
local acompanhando o usuário externo.
Então eles tentarão trabalhar com user
assumindo que é a variável externa, o resultado de authenticateUser()
… A armadilha foi acionada! Olá, depurador…
Existem funções que parecem não mudar nada. Assim como isReady()
, checkPermission()
, findTags()
… Presume-se que eles realizem cálculos, encontrem e retornem os dados, sem alterar nada fora deles. Em outras palavras, sem “efeitos colaterais”.
Um truque muito bonito é adicionar uma ação “útil” a eles, além da tarefa principal.
Uma expressão de surpresa atordoada no rosto de seu colega ao ver uma função chamada is..
, check..
ou find...
mudando alguma coisa – definitivamente ampliará seus limites de razão.
Outra forma de surpreender é retornar um resultado fora do padrão.
Mostre seu pensamento original! Deixe a chamada de checkPermission
retornar não true/false
, mas um objeto complexo com os resultados da verificação.
Os desenvolvedores que tentam escrever if (checkPermission(..))
, se perguntarão por que isso não funciona. Diga a eles: “Leia os documentos!”. E dê este artigo.
O grande Tao flui por toda parte,
tanto para a esquerda quanto para a direita.
Não limite a função pelo que está escrito em seu nome. Seja mais amplo.
Por exemplo, uma função validateEmail(email)
poderia (além de verificar se o e-mail está correto) mostrar uma mensagem de erro e solicitar que você insira novamente o e-mail.
Ações adicionais não devem ser óbvias no nome da função. Um verdadeiro codificador ninja também fará com que eles não sejam óbvios no código.
Unir várias ações em uma protege seu código contra reutilização.
Imagine, outro desenvolvedor deseja apenas verificar o e-mail e não enviar nenhuma mensagem. Sua função validateEmail(email)
que faz as duas coisas não será adequada para eles. Assim, eles não interromperão sua meditação perguntando nada sobre ela.
Todos os “conselhos” acima vêm do código real… Às vezes, escritos por desenvolvedores experientes. Talvez até mais experiente do que você;)
Siga alguns deles e seu código ficará cheio de surpresas.
Siga muitos deles e seu código se tornará verdadeiramente seu, ninguém iria querer alterá-lo.
Siga tudo e seu código se tornará uma lição valiosa para jovens desenvolvedores em busca de esclarecimento.