web-dev-qa-db-ja.com

4つの式での三項演算子の使用

これは許容できるコーディング方法ですか?

public class MessageFormat {
    private static final Color DEFAULT_COLOR = Color.RED;

    private Color messageColor = DEFAULT_COLOR;

    public MessageFormat(Person person) {
        Color color = person.getPreferredColor();
        messageColor = (color != null) ? color : messageColor; // this line
    }
}

または私はクラシックで行く方が良いですか...

if (color != null) {
    messageColor = color;
}
11
Brandon Coffman

?:演算子の使用は、コードを読みやすくするために制限する必要があります。古典的な例:

a = sprintf( "There are %i green bottle%s on the wall.", i, (i==1?"":"s") );

この場合、コードを約5つのif/else行に分割すると、コードが読みにくくなります。

通常、演算子全体を角かっこで囲んでいるので、それを読んだときに、単一の値として精神的に解析されます。

 messageColor = (color != null ? color : messageColor); 

別のバリアントは

messageColor = color || messageColor;

一部の言語では、「color」が「false」に評価されない限り、「color」と評価されます。

最も重要なことは一貫性を保つことであり、そのため、次の人があなたのコードを読んだ場合(たとえそれがあなたであっても)、認知のオーバーヘッドが最小限になります。

この場合、読みやすさ、理解のしやすさなどは同じです(つまり、さあ...)。最初の例の重複と明らかな自己割り当ては好きではありません。それは次のようなものに変換されます:

if (colour != null) {messageColour = colour;}
   else {messageColour = messageColour;};

これは少し愚かです。

通常は2行目を1行で記述しますが、それは個々の派手な応答の問題です。コーディングスタイルのガイドライン:

if (colour != null) {messageColour = colour;};

[〜#〜] edit [〜#〜](私は今8年前より意見が分かれています)

ベストプラクティスを探しているので、

// Use default visibility by default, especially in examples.
// Public needs a reason.
class MessageFormat {
    static final Color DEFAULT_COLOR = Color.RED;

    // Strongly prefer final fields.
    private final Color messageColor;

    // Protect parameters and variables against abuse by other Java developers
    MessageFormat (final Person person) {
        // Use Optionals; null is a code smell
        final Optional<Color> preferredColor = person.getPreferredColor();
        // Bask in the clarity of the message
        this.messageColor = preferredColor.orElse(DEFAULT_COLOR);
    }
}
4
Svante

三項演算子の使用は、他のコーディング標準と同様に、多くの場合敏感な問題です。それの使用は、おそらくあなたのサイトのコーディング標準によって決定されるでしょう。

ただし、この特定の状況では、2番目のオプションをお勧めします。これはより明確であるだけでなく、ここでは三項演算子の使用は完全に不要です。 messageColorをそれ自体に再割り当てする必要はないため、この特定の状況での三項演算子の唯一の機能は、コードの難読化です。

2
Gabriel Reid

三項演算子は、Cプログラマの間でより一般的です。 Cでは、制御構造を回避すると、分岐予測がうまくいかないため、パイプラインを改善できることがよくあります。 Javaでパフォーマンスの違いが見られるとは思いません。if-null-then-assignパターンは、3項よりはるかに一般的です。ただし、既存のコードベースを維持している場合は、通常、既存のコードとの整合性を保つのが最善です。

これを頻繁に行う場合は、defaultIfNullfirstNonNull、またはcoalesce関数を記述して、コードをさらに簡潔にすることができます。 Apache Commons LangにはdefaultIfNull関数が含まれています。

一部の言語には||=演算子。これらの言語でのデフォルト値の通常の慣用句です。

2
brianegge

2番目の方が好きです。つまり、nullでない場合にのみ色を変更したいのです。最初の方法は、これをそれほど明確にしません。

1
Mark Byers

三項演算子は、生成するコードが巧妙でコンパクトに見えるため、しばしば乱用されます。

実際、コードが読みにくくなり、エラーが発生しやすくなります。可能な限り、より長いバージョンのを使用することをお勧めします

 if ( <condition> ) {
     <action> ;
 }

三項構文の代わりに。

1
Alon

あなたの場合、私は「クラシック」実装を好みます。なぜなら、私にとっては、人が好みの色を持っている場合にのみ新しい色を使用したいということを理解する方が速いからです。

NPEを避けたい場合は、メソッド呼び出しで使用することもありますが、通常は次のリファクタリングの1つでこれらの醜いコードを削除します;)

1
Andreas_D

私には問題ないようです(私はPythonの三項演算子をよく使用しています)が、この種のスタイルの問題は通常、非常に主観的です。プロジェクトにコーディングスタイルのドキュメントがある場合は、それを確認できます。

0
djc