何も考えずに学ぶのは労力の無駄です。学ばずに考えることは危険です。
過去のプログラマー忍者は、コード管理者の精神を研ぎ澄ますためにこれらのトリックを使用しました。
コードレビューの達人は、テストタスクでそれらを探します。
初心者の開発者は、プログラマの忍者よりも上手にこれらを使用できることがあります。
それらを注意深く読んで、自分が何者なのか、忍者なのか、初心者なのか、それともコードレビュー担当者なのかを確認してください。
皮肉が検出されました
多くの人が忍者の道をたどろうとします。成功する人はほとんどいません。
コードはできるだけ短くしてください。あなたがどれほど賢いかを示してください。
微妙な言語機能をガイドにしてみましょう。
たとえば、この三項演算子'?'
を見てください。 :
// 有名な JavaScript ライブラリから取得 私=私? i < 0 ? Math.max(0, len + i) : i : 0;
クールですよね?このように書くと、この行に遭遇してi
の値が何であるかを理解しようとする開発者は楽しい時間を過ごすことになるでしょう。そして、答えを求めてあなたのところに来てください。
短い方が常に良いことを伝えてください。彼らを忍者の道に導きましょう。
道は無言の中に隠れています。道だけがよく始まり、よく完成されています。
コードを短くするもう 1 つの方法は、あらゆる場所で 1 文字の変数名を使用することです。 a
、 b
またはc
ように。
森の中の本物の忍者のように、短い変数がコード内で消えます。エディターの「検索」を使用しても誰も見つけることができません。そして、たとえ誰かが知ったとしても、 a
またはb
という名前が何を意味するかを「解読」することはできません。
…ただし、例外もあります。本物の忍者は、 "for"
ループのカウンターとしてi
使用することはありません。どこでも、でもここではない。周りを見回すと、他にもたくさんのエキゾチックな文字があります。たとえば、 x
またはy
です。
ループ本体が 1 ~ 2 ページかかる場合 (可能であればもっと長くしてください)、ループ カウンタとしてのエキゾチックな変数は特に優れています。そうなると、誰かがループの奥深くを調べても、 x
という名前の変数がループ カウンターであることをすぐには理解できなくなります。
チームのルールで 1 文字の曖昧な名前の使用が禁止されている場合は、名前を短くし、略語を作成します。
このような:
list
→ lst
。
userAgent
→ ua
。
browser
→ brsr
。
…等
本当に勘の良い人だけがそのような名前を理解できるでしょう。すべてを短くしてみてください。価値のある人だけがコードの開発を支持できるはずです。
大広場には角がない
偉大な船は最後に完成しました、
大音は稀有な音であり、
偉大なイメージには形がありません。
名前を選ぶときは、最も抽象的な言葉を使用するようにしてください。 obj
、 data
、 value
、 item
、 elem
など。
変数の理想的な名前はdata
です。可能な限りどこでも使用してください。確かに、すべての変数はデータを保持しますよね?
…しかし、 data
がすでに取得されている場合はどうすればよいでしょうか? value
試してみてください。これも普遍的です。結局のところ、変数は最終的に値を取得します。
変数にその型に基づいて名前を付けます: str
、 num
…
試してみてください。若い修練者は疑問に思うかもしれません – そのような名前は忍者にとって本当に役立つのでしょうか?確かにそうです!
確かに、変数名にはやはり意味があります。変数の中に何が入っているか、文字列、数値、その他何かを示します。しかし、部外者がコードを理解しようとすると、実際には情報がまったくないことに驚くでしょう。そして最終的には、よく考えたコードを変更することはできません。
値の型はデバッグによって簡単に確認できます。しかし、変数の意味は何でしょうか?どの文字列/数値が保存されますか?
良い瞑想なしにそれを理解する方法はありません。
…しかし、そのような名前がなくなったらどうなるでしょうか? data1, item2, elem5
の数字を追加するだけです。
本当に注意深くプログラマーだけがコードを理解できるはずです。しかし、それをどうやって確認するのでしょうか?
方法の 1 つは、 date
やdata
の類似した変数名を使用することです。
可能な限りそれらを混ぜてください。
このようなコードを素早く読むことは不可能になります。そして、タイプミスがあると… うーん… 長い間動けず、お茶を飲む時間になりました。
語られる道は永遠の道ではない。名付けられる名前は永遠の名前ではありません。
同じものに似た名前を使用すると、人生がより面白くなり、あなたの創造性を公衆に示すことができます。
たとえば、関数プレフィックスについて考えてみましょう。関数が画面にメッセージを表示する場合は、 displayMessage
のように、 display…
で関数を開始します。そして、別の関数がユーザー名など、他のものを画面に表示する場合は、 show…
( showName
など) で開始します。
このような関数には微妙な違いがあることをほのめかしますが、実際には違いはありません。
チームの仲間の忍者と協定を結びます。ジョンがコード内でdisplay...
を使用して関数を「表示」し始めた場合、ピーターはrender..
使用し、アンはpaint...
使用できます。コードがどれほど興味深く多様になったかに注目してください。
…そしてハットトリック達成!
重要な違いがある 2 つの関数には、同じプレフィックスを使用してください。
たとえば、関数printPage(page)
プリンターを使用します。そして関数printText(text)
テキストを画面上に表示します。馴染みのない読者には、同様の名前の関数printMessage
についてよく考えてもらいましょう。プリンターに送信するのか、画面上に送信するのか?」これを本当に輝かせるには、 printMessage(message)
で新しいウィンドウに出力する必要があります。
全体を分割したら、部分を
名前が必要です。
すでに十分な名前があります。
いつ止めるべきかを知らなければなりません。
新しい変数は絶対に必要な場合にのみ追加してください。
代わりに、既存の名前を再利用します。そこに新しい値を書き込むだけです。
関数では、パラメーターとして渡される変数のみを使用するようにしてください。
そうなると、変数の中に何が入っているのかを正確に特定することが非常に難しくなります。そしてそれがどこから来たのかも。目的は、コードを読む人の直感と記憶力を養うことです。直感が弱い人は、コードを 1 行ずつ分析し、すべてのコード分岐の変更を追跡する必要があります。
このアプローチの高度な変種は、ループまたは関数の途中で値を秘密裏に (!) 同様のものに置き換えることです。
例えば:
関数 ninjaFunction(elem) { // elem を扱う 20 行のコード elem = クローン(elem); // さらに 20 行で、要素のクローンを操作できるようになりました。 }
関数の後半でelem
を使用したいプログラマ仲間は驚くでしょう…デバッグ中にのみ、コードを調べた後、クローンを使用していることがわかります。
コード内で定期的に見られます。経験豊富な忍者に対しても致命的な効果を発揮します。
変数名の前にアンダースコア_
と__
付けます。 _name
や__value
のように。それらの意味を知っていただければ幸いです。あるいは、特に意味を持たずに、ただ楽しむために追加することもできます。あるいは、場所によって意味が異なることもあります。
一撃で二匹のウサギを殺します。第一に、コードが長くなり、読みにくくなります。第二に、開発者仲間がアンダースコアの意味を理解するのに長い時間を費やす可能性があります。
賢い忍者は、コードの 1 つの場所にアンダースコアを置き、他の場所ではアンダースコアを回避します。これにより、コードがさらに脆弱になり、将来エラーが発生する可能性が高くなります。
あなたの実体がどれほど素晴らしいかをみんなに見てもらいましょう! superElement
、 megaFrame
、 niceItem
などの名前は、間違いなく読者を啓発するでしょう。
確かに、一方では、何かが書かれています: super..
、 mega..
、 nice..
しかし、もう一方からは、詳細はわかりません。読者は、隠された意味を探して、有給労働時間の 1 ~ 2 時間瞑想することに決めるかもしれません。
明るいところにいると、暗闇では何も見えません。
暗闇の中でも光があればすべてが見える。
関数内と関数外の変数には同じ名前を使用します。シンプルに。新しい名前を考え出す努力はありません。
let user =authenticateUser(); 関数 render() { let user = anotherValue(); ... ...たくさんの行... ... ... // <-- プログラマはここでユーザーと協力したいと考えています... ... }
render
内側にジャンプするプログラマは、おそらく、外側のレンダリングをシャドウしているローカルuser
存在に気付かないでしょう。
次に、それが外部変数、 authenticateUser()
の結果であると想定して、 user
を操作しようとします…罠が仕掛けられています。こんにちは、デバッガー…
何も変わっていないように見える関数もあります。 isReady()
、 checkPermission()
、 findTags()
と同様に、外部には何も変更せずに、計算を実行し、データを検索して返すことが想定されています。言い換えれば、「副作用」がないということです。
本当に美しいトリックは、メインのタスクに加えて「役立つ」アクションを追加することです。
is..
、 check..
またはfind...
という名前の関数が何かを変更しているのを見たときに同僚が呆然とした驚きの表情を浮かべると、間違いなくあなたの理性の境界が広がります。
驚くもう 1 つの方法は、標準以外の結果を返すことです。
あなたの独創的な思考を発揮してください! checkPermission
の呼び出しでtrue/false
ではなく、チェックの結果を含む複合オブジェクトを返すようにします。
if (checkPermission(..))
を書こうとする開発者は、なぜそれが機能しないのか疑問に思うでしょう。 「ドキュメントを読んでください!」と伝えてください。そしてこの記事をあげてください。
偉大なタオはどこにでも流れ、
左にも右にも。
名前に書かれている内容によって機能を制限しないでください。もっと広くなりましょう。
たとえば、関数validateEmail(email)
(電子メールが正しいかどうかをチェックする以外に) エラー メッセージを表示し、電子メールの再入力を求めることができます。
追加のアクションは関数名からは明らかではありません。本物の忍者コーダーは、コードからはそれらが明らかではないようにします。
複数のアクションを 1 つに結合すると、コードが再利用されないように保護されます。
別の開発者が電子メールをチェックするだけで、メッセージを出力したくないと考えていると想像してください。両方を実行する関数validateEmail(email)
それらに適合しません。したがって、彼らは瞑想について何かを尋ねることによってあなたの瞑想を中断することはありません。
上記のすべての「アドバイス」は実際のコードからのものです…場合によっては、経験豊富な開発者によって書かれています。もしかしたらあなたよりも経験豊富かもしれません ;)
それらのいくつかに従えば、あなたのコードは驚きに満ちたものになるでしょう。
それらの多くに従えば、あなたのコードは真にあなたのものになり、誰もそれを変更したくなくなります。
すべてに従ってください。そうすれば、あなたのコードは啓発を求める若い開発者にとって貴重な教訓になります。