ブール割り当てのベストプラクティス[終了]


10

別の開発者から引き継いだプログラムで、次の条件に遭遇しました。

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

このコードは冗長で見苦しいと思うので、比較に基づいて単純なブール割り当てと考えていたものに変更しました。

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE;

これを見ると、私のコードをレビューしている人が、私の変更は機能的には正しいものの、他の人がそれを見て混乱させるかもしれないとコメントしました。彼は、三項演算子を使用すると、この割り当てがより明確になると信じていますが、私はより冗長なコードを追加するのは好きではありません:

obj.NeedsChange = (obj.Performance <= LOW_PERFORMANCE) ? true : false;

彼の推論は、他の開発者があなたがやったことを正確に止めて困惑させなければならないなら、最も簡潔な方法で何かをすることは価値がないということです。

ここでの本当の問題は、ブール値に値を割り当てるこれら3つの方法のうち、どれがobj.NeedsChange最も明確で保守しやすいのかということです。


25
3番目の形式はばかげています。それは、第2の形式ですでに露骨に明らかであるはずのものを述べているだけです。
ロバートハーヴェイ

6
これは完全に個人の好み次第です。それ以外のふりをすることもできますが、それらはすべて機能的に同等であるため、結局はstyleになります。確かに、読みやすさに差がありますが、私は「読みやすく、透明」あなた「鈍角と不透明」であるかもしれない
MetaFight

3
@scriptin 5-8行v 1行は好みよりも多く、5-8ライナーは通常より明確で優れています。この単純な例では、1行を好みますが、一般的に、快適さのために1ライナーに難読化された10ライナーが多すぎます。それを考えると、私はバリアント1について文句を言うことはありませんが、きれいではないかもしれませんが、同じようにはっきりと明らかに仕事をします。
gbjbaanb

4
オプション1と3は、「著者はブール論理を本当に理解していない」と言っています。

2
バリアント1は、値に依存するブレークポイントを頻繁に設定する必要がある場合に役立ちます。
イアン

回答:


39

私は2を好むが、私はそれに少し調整をするかもしれない:

obj.NeedsChange = ( obj.Performance <= LOW_PERFORMANCE );

私にとって、括弧は行を解析しやすくし、比較結果を割り当てていること、そして二重割り当てを実行していないことを一目で明らかにします。なぜそうなるのかはわかりません(かっこで実際に二重の代入を妨げるような言語は考えられません)が、レビュアーを満足させる必要がある場合は、おそらくこれは許容できる妥協案でしょう。


4
これは正しい答えです-質問のコードは正しいですが、括弧を追加すると、それは割り当てとしてではないことを読者に伝えます。コードをすばやく見る場合、括弧は、そのコードがそのようなものであるのか、偶然のバグではないかを確認するために、すぐに余分な情報を提供します。たとえば、行がであったと想像a = b == cしてください。boolを割り当てることを意味しましたか、またはbとaの両方にcを割り当てることを意味しましたか。
gbjbaanb

括弧は、Pythonでの二重割り当てを防ぎます。二重代入を妨げない言語でも、括弧は間違いなく2種類の操作を扱っていることを示すのに役立ちます。
user2357112は

23

バリアント1は簡単に理解できますが、それが唯一の利点です。このように書く人は、ブール値が何であるかを本当に理解しておらず、他の多くの点で同様の幼児コードを書くことになると自動的に仮定します。

バリエーション2は、私がいつも書くもので、読むことを期待しているものです。そのイディオムに混乱している人は、ソフトウェアのプロのライターであってはならないと思います。

バリアント3は、1と2の両方の短所を兼ね備えています。


まあ、バリアント2を有する変異体1株その利点...
デュプリケータ

1
幼児コードの場合は+1。私は何年もそのようなコードを見てきましたが、それを識別する正しい言葉が不足していました。
リリエンタール

1
バリアント1のようなコードに関する最初の仮定は、過去のある時点での2つのブランチがより複雑であり、リファクタリング時に誰かが注意を払っていなかったということです。しかし、それが最初に書かれたときのやり方だった場合、「ブール値を理解していない」
ことに

13

いつでもコードは、「これが何をしているのか」をトリガーする必要があるよりも複雑です。読者の匂い。

たとえば、最初の例では、「削除されたある時点でif / elseステートメントに他の機能がありましたか?」

例(2)はシンプルで明確で、必要なことを正確に行います。私はそれを読み、コードが何をするのかすぐに理解します。

(3)の余分な毛羽立ちにより、著者が(2)の代わりになぜそのように書いたのか疑問に思うでしょう。理由があるはずですが、この場合はそうではないようですので、構文はそこに存在しない何かを示唆しているため、まったく役に立たず、読みにくくなります。存在するもの(何もない場合)を学習しようとすると、コードが読みにくくなります。


2

Variant 2とVariant 1は、一連の明白で単純なリファクタリングによって関連付けられていることが簡単にわかります。

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

ここでは、不必要なコードの重複があり、割り当てを除外できます。

obj.NeedsChange = if (obj.Performance <= LOW_PERFORMANCE)
{
    true
}
else
{
    false
}

またはより簡潔に書かれた:

obj.NeedsChange = if (obj.Performance <= LOW_PERFORMANCE) true else false

条件がtrueの場合、trueが割り当てられ、条件がfalseの場合、falseが割り当てられることがすぐにわかるはずです。IOWは、単純に条件の値を割り当てます。つまり、

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE

バリアント1と3は、比較の戻り値が何であるかを理解していない人によって書かれた典型的なルーキーコードです。


あなたのif(...)... false部分をコメントとしてコメントの直前に追加すると、コードの明快さとより良いコードを簡単にスキャンできます。
DaveM

2

あなたのプログラミングは「コードを維持する人があなたの住んでいる場所を知っている暴力的なサイコパスであるかのように」暗黙的で暗黙的である傾向があります、あなたのサイコの後継者が有能であるいくつかの基本的な事柄仮定することができます。

それらの1つは、彼が使用している言語の構文です。

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE;

C / C ++ / C#/ Java / Javascriptシンタックスを知っている人なら誰でも非常に明確です。

また、8行よりもはるかに読みやすくなっています。

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.NeedsChange = false;
}

間違いを起こしにくい

if (obj.Performance <= LOW_PERFORMANCE)
{
    obj.NeedsChange = true;
}
else
{
    obj.Needschange = false;
}

そして、あたかも言語の構文を忘れているかのように、不要な文字を追加するよりも優れています。

obj.NeedsChange = obj.Performance <= LOW_PERFORMANCE ? true : false;

obj.NeedsChange = (obj.Performance <= LOW_PERFORMANCE);

多くの言語のCライクな構文には、多くの誤りがあると思います:一貫性のない操作の順序、一貫性のない左/右の結合、記号のオーバーロードの使用、ブレース/インデントの複製、三項演算子、中置記法など

しかし、解決策は、独自の独自バージョンを発明することではありません。誰もが自分自身を作成するので、その方法は狂気にあります。


一般に、Real World TMコードを読み取り不能にする一番の理由はその量です。

病的でない200行のプログラムと、まったく同じ1,600行のプログラムの間では、短いプログラムの方がほとんど常に解析と理解が容易です。いつでもあなたの変更を歓迎します。


1

ほとんどの開発者は、2番目のフォームをひと目で理解できます。私の意見では、第1の形式のような単純化は単に不要です。

次のようなスペースとブレースを追加することで、読みやすくすることができます。

obj.NeedsChange =    obj.Performance <= LOW_PERFORMANCE;

または

obj.NeedsChange = ( obj.Performance <= LOW_PERFORMANCE );

ジェイコブ・ライレが述べたように。

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