命名:明快さのために簡潔さを犠牲にするべきですか?


11

たとえば、次の関数は、入力フィールドの名前とエラーを含む配列をループします。これは、検証フィールドの名前を確認し、エラー情報を無効なフィールド配列にプッシュすることにより行います。

簡潔にこれを書く方が良いですか?

addInvalidField (field, message) {
  const foundField = this.invalidFields.find(value => {
    return value.name === field.name
  })
  const errors = foundField.errors
  if (!errors.some(error => error.name === message)) {
    errors.push({ name: message, message })
  }
},

または、このように具体的にしますか?

addInvalidField (validatingField, message) {
  const foundField = this.invalidFields.find(invalidField => {
    return validatingField.name === invalidField.name
  })
  if (!foundField.errors.some(foundFieldError => foundFieldError.name === message)) {
    fouldField.errors.push({ name: message, message })
  }
},

1
関連(おそらく重複):短い変数名の言い訳はありますか?
gnat

答えを書く気はありませんが、私たちは常に名前の長さと明快さの間の良い妥協点を見つけようとします。短い名前は元のプログラマーには明らかですが、他の全員には明らかではありません。長い名前は、コードを読むのに苦労します。間に妥協点があります。
MetalMikester

1
より多くのコメントが必要
Ewan

サイドノート、それがあなたのコードで可能かどうかはわかりませんが、invalidFieldsなどが配列ではなくマップに保存されている場合、このコードははるかに簡単になります。
user949300

1
@alexコメントへの回答として、Marijn HaverbekeによるEloquent JavaScriptのコピーを入手または借りることができる場合(2014年版)、73-75ページに移動して、配列の代わりにマップを使用する素晴らしい例をご覧ください。お役に立てば幸いです。
user949300 16

回答:


23

明快さのために簡潔さを犠牲にすることができるなら、そうすべきです。しかし、明快さのために冗長性を犠牲にすることができれば、さらに良いでしょう。

addInvalidField (field, message) {
  const foundInvalidField = this.invalidFields.find(x => x.name === field.name)
  if (!foundInvalidField.errors.some(x => x.name === message)) {
    foundInvalidField.errors.push({ name: message, message })
  }
},

変数が1行だけ存続する場合、実際には非常に短くなる可能性があります。 FoundInvalidFieldは3行で使用され、この作業の焦点です。説明的な名前に値します。

いつものように、コンテキストは王様です。


2
明快さのために簡潔さを犠牲にすることができるなら、 + 1 私がほとんどすべての状況で明快さを追求するときでさえ。しかし、それは明確に引用可能な引用です。
Tulainsコルドバ

12

実際、最初のコード例を優先します。

コードを読むだけでコードが何をするのかは明らかです。変数名を可能な限り小さくすることで、コードがさらに読みやすくなります。関数がより長く、変数がより多く、および/または変数がより大きなコードスコープで使用された場合にのみ、よりわかりやすい変数名が必要になります。

関数を簡潔にしたため、変数名も簡潔に保つことができます。他のすべての条件が同じであれば、コードが少ないほど常に優れています。


2
これに便乗するために、一般的なルールとして、メソッド/関数にはより小さな変数名を使用します。より詳細な名前を使用するのは、名前空間の競合がある場合のみです。ただし、関数のサイズが小さい場合、これも簡単に実行できます。
-unflores

4
私は、詳細な名前が本当に好きな人と仕事をしました。変数とメソッド名は基本的に完全な英語の文でした(例:theResultOfMethodDoFooWithBar)。これは物事を明確にするはずであるという考えでしたが、その綿毛をすべて(精神的に)解析しようとすると頭痛の種になりました。この例では、メソッドがフィールド検証に関するものであることはすでにわかっています。他の「フィールド」パラメーターはありません。「validatingField」などの名前を使用すると、明快さが追加されず、スキミングの際に重要な情報がわかりにくくなります。
ジミージェームズ

@unflores私もそうしようとしています。validatingFields検証付きのフォームフィールドです。元の名前はでしたfieldWithValidation。この短い名前を見つけるのは本当に難しいです。私はそれを呼び出すことができますfieldが、その後field、メソッド内の別のものと競合します。
アレックス

4

ボブおじさんには、過度の冗長さを招くことなく明快さを好むことに同意すると思う。あなたが示す例では、過度の冗長性を招くことなく、2番目の意図がより明確であると言います。また、のコードベースを検索する場合、の場合よりも特定のスニペットを見つける方が簡単invalidFieldですvalue


さて、ここでクリーンコードを引用しています(ボブおじさんの説教にうんざりしている場合はスキップしてください(私はそうではありません):

意図を明らかにする名前を使用する

名前は意図を明らかにすべきだと言うのは簡単です。私たちがあなたに印象づけたいのは、私たちはこれについて真剣だということです。適切な名前を選択するには時間がかかりますが、必要以上に節約できます。したがって、名前に注意し、より良い名前が見つかったら名前を変更してください。あなたのコードを読む人(あなたを含む)は、そうすれば幸せになります。


偽情報を避ける

プログラマは、コードの意味を曖昧にする誤った手がかりを残さないようにしなければなりません。定着した意味が私たちと異なる言葉を避けるべきです


有意義な区別をする

プログラマーは、コンパイラーまたはインタープリターを満足させるためだけにコードを作成すると、自分で問題を作成します。


検索可能な名前を使用する

あなたがするのに役立つ名前を使用してくださいgrep -iIR whateveryouaresearching . (クリーンコードではなく、ここではCCは1文字の変数についてのみ話しました)。


メンタルマッピングを避ける

読者は、あなたの名前を頭の中で知っている他の名前に翻訳する必要はないはずです。通常、この問題は、問題ドメイン用語もソリューションドメイン用語も使用しないという選択から発生します。


問題のあるドメイン名を使用する

あなたがやっていることに対して「プログラマー」が存在しないときは、問題のあるドメインの名前を使用してください。少なくとも、コードを保守するプログラマーは、ドメインエキスパートにその意味を尋ねることができます。



1

私は最近、よりわかりやすいものにすることを常に望んでいます。IDEコードの補完は、記述的な変数名を書く必要がないので、マイナス面が見えないことを意味します。

先史時代に戻って、変数名の制限があり、意味のある変数名を使用すると、実際に測定可能なコストが発生する可能性がありますプロセッサ、実際に重要なループで数クロックサイクルを節約)


6
欠点は、たくさん入力しなければならないということではありません。入力は1回のみです。長すぎる名前の欠点は、読むのが難しくなることです。また、コードベースの寿命にわたって読み取りが何度も発生するため、また読み取りが深く根付いているために問題の原因に意識的に気付かないため、それは潜行性です。
キリアンフォス

そして、もしあなたが変数について何かを覚えようとするために時間とコンテキストシフトを費やさなければならないなら、それは十分に説明的ではなかったので、より多くの時間がかかります:)。
mcottle

1

2番目のバリエーションは、私を困惑させます。署名だけを見ると、フィールドが既に無効であると認識されているのでしょうか?またはvalidatingField、それが実際に無効であるかどうかを調べるために、最初に検証されますか?したがって、これは単なる冗長な情報ではなく、余分な情報はやや誤解を招くように思われます。この種の「明確さ」は明確ではなく、その反対です。

実際、あなたの最初の機能を見たとき、それも私を困惑させました。私は、なぜあなたの機能がフィールドを取得するだけなのかを自問しましたが、それを使用せずに別のフィールドを検索しinvalidFieldsますか?次のように、フィールド名を指定するだけでフィールドを検索するのがはるかに理にかなっているようです。

addInvalidField (fieldname, message) {
  const foundField = this.invalidFields.find(value => {
    return value.name === fieldname
  })
  const errors = foundField.errors
  if (!errors.some(error => error.name === message)) {
    errors.push({ name: message, message })
  }
}

ただし、ボブ・マーティンはさらに一歩進んで、コードをより詳細にするために-より明確にするために-別の方向に進むと思います。「Clean Code」ブックの行に沿った典型的なリファクタリングは、おそらく次のようになります。

addInvalidField (fieldname, message) {
  const foundField = findInvalidField(fieldName)
  addMessageForInvalidField(foundField,message)
}

3つの追加機能

  findInvalidField(fieldname){
    return this.invalidFields.find(value => { return value.name === fieldname })
  }

  addMessageForInvalidField(field,message){
    const errors = field.errors
    if (!doesErrorsContain(message)) {
      errors.push({ name: message, message })
    }
  }

  doesErrorsContain(message){
     return errors.some(error => error.name === message)
  }

単一の責任原則でそれまでの成果を上げるかどうかは議論の余地があります。実際には長所と短所があります。私の個人的な観点では、元のコードはほとんどの製品コードに対して「十分にクリーン」ですが、リファクタリングされたコードの方が優れているということです。

最初のバリアントに何かを追加しなければならないとわかったとき、それをこれらの小さな関数に分割して、コードが混乱することさえないようにします。


validatingFields検証のあるフォーム内のフィールドです。最初は名前を付けましfieldsWithValidationたが、少し長かったです。
アレックス

0

命名の一般的な正しい答えはありません。まったく同じタスクセットを与えられた多くの人は、結果の関数と変数に非常に異なる名前を付けます。もちろん、コードを読んでいる他の人に理解してもらいたいのですが、長ければ長いほど、何かが明確になるとは限りません。コードの密度が高い場合は、コードの密度を上げる必要があります。関数のすべての行ができる限り明確で記述的であることを理解するには、さらに時間がかかります。

個人的には、最初の例のほうが好きです。変数は、2番目の例のように説明的な名前を持たない場合でも、まっすぐです。正直なところ、2番目の例の変数名は私の意見では1番目の変数よりも明確ではないため、関数を簡潔にすると関数自体を理解しやすくなります。

結局のところ、どちらが良いかはあなたとあなたが一緒に仕事をしている人次第です。結局のところ、それはそれを読んで維持する人です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.