web-dev-qa-db-ja.com

戻り値の計算とreturnステートメントを1行のメソッドに分割しますか?

returnステートメントと、2行で戻り値を計算するステートメントを壊すことについて、同僚と話し合いました。

例えば

private string GetFormattedValue()
{
    var formattedString = format != null ? string.Format(format, value) : value.ToString();
    return formattedString;
}

の代わりに

private string GetFormattedValue()
{
    return format != null ? string.Format(format, value) : value.ToString();
}

コード的には、最初のバリアントには値がありません。私にとっては、特に短い方法の場合、後者の方が明確です。彼の主張は、前者のバリアントはデバッグが容易であるというものでした。VisualStudioでは、ブレークポイントが原因で実行が停止したときにステートメントを非常に詳細に検査できるため、これは非常に小さなメリットです。

私の質問は、デバッグを簡単にするために、コードをあまり明確に記述しないことが有効な点であるかどうかです。その他の引数はありますかfor分割計算とreturnステートメントのバリアント?

26
Paul Kertscher

変数の説明の導入は よく知られたリファクタリング であり、複雑な式を読みやすくするのに役立つ場合があります。ただし、示されているケースでは、

  • 追加の変数は、周囲のメソッド名から明確でないものを「説明」しません
  • ステートメントがさらに長くなるため、(少し)読みにくくなります

さらに、Visual Studioデバッガーの新しいバージョンでは、ほとんどの場合、余分な変数を導入しなくても関数の戻り値を表示できます(ただし、いくつかの注意点があります this old SO投稿とさまざまな回答 )。

したがって、この特定のケースでは、私はあなたに同意しますが、説明変数が実際にコード品質を向上させることができる他のケースがあります。

46
Doc Brown

その事実を考えると:

a)コンパイラーが変数を最適化するため、最終的なコードへの影響はありません。

b)分離すると、デバッグ機能が向上します。

個人的には、99%の時間でそれらを分離することが良い習慣であるという結論に達しました。

この方法でそれを行うことに重大な欠点はありません。肥大化したコードは、判読不能なコードやデバッグが困難なコードと比較して取るに足らない問題であるため、コードが肥大化するという主張は誤称です。さらに、このメソッド自体が混乱を招くコードを作成することはできません。それは完全に開発者次第です。

38
Dom

多くの場合、結果に名前を付けるためだけに変数を導入すると、コードがより自己文書化するときに非常に役立ちます。この場合、変数名はメソッド名に非常に似ているため、これは要因ではありません。

1行メソッドには固有の値がないことに注意してください。変更によってより多くの行が導入されるが、コードがより明確になる場合、それは良い変更です。

しかし、一般的に、これらの決定は個人の好みに大きく依存します。例えば。条件演算子が不必要に使用されているため、両方のソリューションが混乱しています。私はifステートメントを優先しました。しかし、あなたのチームでは、さまざまな規約に同意している可能性があります。次に、慣例が示唆することをすべて実行します。このようなケースで規約が沈黙している場合、これは長期的には問題にならない非常に小さな変更であることに注意してください。このパターンが繰り返し発生する場合は、チームとしてこれらのケースをどのように処理したいかについて話し合う可能性があります。しかし、それは「良いコード」と「おそらく少しだけ良いコード」との間で髪の毛を分けています。

16
amon

あなたの質問に答えて:

私の質問は、コードをより明確に記述せずにデバッグすることを簡単にするために、それでもまだ有効なポイントであるかどうかです。

はい。実際、あなたの以前の発言の一部は、私(気分を害するものではない)が少し近視眼的であるように見えます(以下の太字を参照) "彼の引数は、前者のバリアントがデバッグしやすいということでした-これはかなり小さなメリットです、VisualStudioでは非常に詳細なブレークポイントのために実行が停止したときのステートメントの検査。 "

デバッグを容易にすることは、(ほぼ)「小さなメリット」では決してありません。これは、プログラマの時間の50%がデバッグに費やされるためです( リバーシブルデバッグソフトウェア ) 。

split計算とreturnステートメントでバリアントに他の引数はありますか?

はい。一部の開発者は、分割計算の方が読みやすいと主張します。もちろん、これはデバッグに役立ちますが、コードが実行または適用するビジネスルールを誰かが解読しようとしているときにも役立ちます。

注:ビジネスルールは頻繁に変更される可能性があるため、データベースで提供するほうが適切な場合があります。それにもかかわらず、この領域での明確なコーディングは依然として最優先事項です。 ( ビジネスルールエンジンの構築方法

2
tale852150

私はさらに行きます:

private string GetFormattedValue()
{
    if (format != null) {
        formattedString = string.Format(format, value);
    } else {
        formattedString = value.ToString()
    }
    return formattedString;
}

どうして?

より複雑なロジックに3項演算子を使用すると判読できなくなるため、より複雑なステートメントには上記のようなスタイルを使用します。このスタイルを常に使用することにより、コードは一貫しており、人間が解析しやすくなります。さらに、この種の一貫性を導入することで(そしてコードリントや他のテストを使用することで)goto failタイプエラー。

もう1つの利点は、formatのテストがnullでないことを含めるのを忘れた場合に、コードカバレッジレポートで通知されることです。これは三項演算子には当てはまりません。


私が好む代替案-メソッドからの複数のリターンに対してではなく、「できるだけ早く群集を返す」場合:

private string GetFormattedValue()
{
    if (format != null) {
        return string.Format(format, value);
    }

    return value.ToString();
}

したがって、最後のリターンを見て、デフォルトが何であるかを確認できます。

ただし、一貫性を保つことが重要であり、すべてのメソッドがいずれかの規則に従うようにする必要があります。

1
HorusKol

このような手法は、デバッグの必要性によって正当化できるとは思いません。私はこのアプローチに1000回遭遇しました。時々、私はこれを続けていますが、常に Martin Fowlerがデバッグについて言った を覚えています。

人々はまた、デバッグに費やす時間を過小評価しています。彼らは、長いバグの追跡に費やすことができる時間を過小評価しています。テストでは、バグを追加したときにすぐにわかります。これにより、クロールして非表示になる前に、すぐにバグを修正できます。デバッグよりもイライラしたり時間を浪費したりすることはほとんどありません。そもそもバグを作成していなかったとしたら、もっと早くならないでしょうか?

1
Zapadlo

三項演算子のように、この問題に関係のある問題に悩まされている人もいると思います。はい、多くの人が嫌いなので、とにかく育てたほうがいいかもしれません。

質問の焦点に関して、返されたステートメントを変数によって参照されるように移動します...

この質問は、私が同意しない2つの仮定を行います。

  1. 2番目のバリアントがより明確または読みやすいこと(私は反対が真実であると言います)、および

  2. 誰もがVisual Studioを使用していること。 Visual Studioを何度も使用してきましたが、問題なく使用できますが、通常は別のものを使用しています。特定のIDEを強制する開発環境は、私が疑っている環境です。

名前付き変数に何かを分割しても、読み取りが困難になることはめったになく、ほとんど常に逆のことが行われます。特定のmannerでは、セルフドキュメンテーションのオーバーロードがvar thisVariableIsTheFormattedResultAndWillBeTheReturnValue = ...それでは明らかにそれは悪いことですが、それは別の問題です。 var formattedText = ... 結構です。

この特定のの場合、および1-linersについて話しているため、おそらく多くの場合、変数は関数名がまだあなたに伝えていないことをあまり伝えません。したがって、変数はそれほど追加されません。デバッグの引数は引き続き有効ですが、この特定のケースでは、デバッグ時に焦点となる可能性のあるものは何も表示されません。デバッグのために何らかの形式が必要な場合などは、後で簡単に変更できます。

一般的に、あなたは一般的なルールを求めました(あなたの例はそれだけで、一般化されたフォームの例です)、バリアント1(2-liner)を支持してなされたすべてのポイントは正しいです。それらは良いガイドラインです。しかし、ガイドラインは柔軟である必要があります。たとえば、現在取り組んでいるプロジェクトでは、1行あたり最大80文字なので、lotの行を分割しますが、分割するのが面倒な81-85文字の行を見つけたり、読みやすさを減らし、私はそれらを制限を超えて残します。

値を追加することはほとんどないので、特定の例では2行は行いません。この場合、ポイントが他の方法で実行するほど強力ではないため、バリアント2(1ライナー)を実行します。

1
Aaron