たとえば、次の関数は、入力フィールドの名前とエラーを含む配列をループします。これは、検証フィールドの名前を確認してから、エラー情報を無効なフィールド配列にプッシュすることによって行われます。
簡潔にこれを書く方が良いですか:
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 })
}
},
簡潔にするために簡潔さを犠牲にすることができる場合は、それをすべきです。しかし、冗長性を明確にするために犠牲にすることができれば、さらに良いでしょう。
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番目の意図は、過度の冗長性を招くことなく、より明確であると言えますです。また、invalidField
よりもvalue
のコードベースを検索する方が、特定のスニペットを見つけやすくなります。
まあ私はここでクリーンコードを引用しています(ボブおじさんの説教にうんざりしている場合はスキップしてください(私はそうではありません):
意図を明らかにする名前を使用
名前は意図を明らかにすべきだと言うのは簡単です。私たちがあなたに印象づけたいのは、これについて真剣に取り組んでいるということです。適切な名前を選択するには時間がかかりますが、それ以上の節約になります。だからあなたの名前に気をつけて、より良い名前を見つけたらそれらを変えてください。あなたを含めてあなたのコードを読む人は誰でも幸せになります。
偽情報の回避
プログラマーは、コードの意味を曖昧にする誤った手掛かりを残さないようにする必要があります。定着した意味が私たちと異なる言葉は避けるべきです
有意義な区別をする
プログラマーは、コンパイラーまたはインタープリターを満足させるためだけにコードを作成するときに、自分自身で問題を作成します。
検索可能な名前を使用
grep -iIR whateveryouaresearching .
を実行するのに役立つ名前を使用してください(クリーンコードではなく、ここではCCは1文字の変数についてのみ説明しました)。
メンタルマッピングを回避
読者はあなたの名前を彼らがすでに知っている他の名前に精神的に翻訳する必要はありません。この問題は一般に、問題ドメイン用語もソリューションドメイン用語も使用しないという選択から発生します。
問題のあるドメイン名を使用
何をしているのかがわからない場合は、問題のあるドメインの名前を使用してください。少なくとも、コードを管理するプログラマは、ドメインの専門家にそれが何を意味するのか尋ねることができます。
私は常にこれらの日をより説明的にすることを選びます-IDEコード補完は、説明的な変数名を書く必要がないので、私は欠点を見ることができません。
先史時代に戻ると、変数名の制限があり、意味のある変数名を使用すると、実際に測定可能なコストが発生する可能性があります(たとえば、BBC BASICでは、整数の静的変数A%などを使用すると、意味のある整数を使用するよりもはるかに安価で、1 MHzのシステムではプロセッサ、ループ内の数クロックサイクルの節約が実際に重要)
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 })
}
}
ただし、ボブマーティンはおそらくさらに一歩進んで、コードをより明確にするために、別の方向に向けてコードをより冗長にするでしょう。 「クリーンコード」の本に沿った典型的なリファクタリングは、おそらく次のようになります。
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)
}
それが単一責任の原則でそれまでに行くために報われるかどうかは議論の余地があります。実際には、いくつかの長所と短所があります。私の個人的な見解では、元のコードはほとんどの製品コードに対して「十分にクリーン」ですが、リファクタリングされたコードの方が優れています。
最初のバリアントに何かを追加する必要があることがわかったので、それをどんどん大きくするために、あらかじめこれらの小さな関数に分割して、コードがめちゃくちゃにならないようにします。
ネーミングに関しては一般的に正解はありません。多くの人は、まったく同じタスクのセットを与えられると、結果の関数と変数に非常に異なる名前を付けます。もちろん、あなたはあなたのコードを読んでいる他の人に理解してもらいたいですが、それが長いからといって、何かがより明確であるとは限りません。コードの密度が高い場合は、それが必要であり、関数のすべての行ができるだけ明確で説明的であっても、理解するのに時間がかかります。
個人的には、最初の例の方が好きです。 2番目の例のように変数に説明的な名前が付いていなくても、簡単です。正直なところ、2番目の例の変数名は、私の考えでは最初のものよりも明確ではなく、関数を簡潔にしておくと、関数自体を理解しやすくなります。
結局のところ、どちらを使用するかはあなた次第です。結局のところ、それはそれを読んで維持する人です。