2009-11-29 8 views
11

Ist dies eine akzeptable Codierungspraxis?Verwenden eines ternären Operators mit 4 Ausdrücken

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 
    } 
} 

oder bin ich besser dran mit dem klassischen gehen ...

if (color != null) { 
    messageColor = color; 
} 
+1

Es ist formal die __conditional operator__, [ nach der JLS] (http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.25). Technisch könnte es andere ternäre Operatoren geben, genauso wie es zahlreiche binäre Operatoren gibt, obwohl Java derzeit keine hat. – Pops

Antwort

24

Die Verwendung des Operators?: Sollte darauf beschränkt sein, den Code lesbarer zu machen. Ein klassisches Beispiel:

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

In diesem Fall wäre der Code weniger lesbar, wenn Sie es in etwa auflösen 5 if/else Linien.

Ich lege normalerweise Klammern um den gesamten Operator, so dass ich es beim Lesen mental als einen einzigen Wert analysiere.

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

Eine andere Variante ist

messageColor = color || messageColor; 

die in einigen Sprachen auswerten wird „Farbe, es sei denn, Farbe wertet auf‚false‘, in welchem ​​Fall Wert von messageColor. Meiner Meinung nach sollte dies als vermieden werden kann es die Menschen verwirren.

das wichtigste im Einklang sein, so dass die nächste Person, Ihren Code zu lesen (auch wenn du es ist) Mindest kognitiven Aufwand hat.

+0

gutes Beispiel. Einfach zu verstehen. –

0

Scheint gut zu mir (ich benutze Python ternären Operator viel), aber diese Art von Stil Thema ist in der Regel sehr subjektiv . Wenn das Projekt über ein Codierungsstildokument verfügt, sollten Sie dies überprüfen.

1

Ich bevorzuge die zweite, weil es deutlicher ausdrückt, was Sie meinen: Sie wollen nur die Farbe ändern, wenn sie nicht null ist. Die erste Methode macht das nicht so klar.

2

Die Verwendung des ternären Operators ist oft ein heikles Thema, zusammen mit anderen Codierungsstandards. Die Verwendung wird wahrscheinlich am besten durch Kodierungsstandards auf Ihrer Website bestimmt.

Allerdings würde ich in dieser speziellen Situation definitiv die zweite Option empfehlen; es ist nicht nur klarer, aber die Verwendung des ternären Operators ist hier völlig überflüssig. Es ist nicht notwendig, messageColor für sich selbst neu zuzuordnen, daher ist die einzige Funktion des ternären Operators in dieser speziellen Situation die Codeverschleierung.

1

Ternäre Operatoren werden oft missbraucht, weil der Code, den sie erzeugen, clever und kompakt erscheint.

In der Tat machen sie den Code weniger lesbar und fehleranfälliger. Wann immer möglich, ist es ratsam, die längere Version

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

Statt einer ternären Syntax zu verwenden.

+0

nicht vollständig wahr: ternäre Operatoren können Code lesbarer machen (nicht immer, stimme ich zu) –

2

Der ternäre Operator ist häufiger unter C-Programmierern. In C, wenn Sie Kontrollstrukturen vermeiden, können Sie häufig bessere Pipelining erhalten, da keine Verzweigungsvorhersage falsch ist. Ich bezweifle, dass Sie einen Leistungsunterschied in Java sehen würden, und das If-Null-Take-Assign-Muster ist viel häufiger als das Ternär. Wenn Sie jedoch eine vorhandene Codebasis beibehalten, ist es normalerweise am besten, mit dem vorhandenen Code zu konsistent zu bleiben.

Wenn Sie sich dabei häufig befinden, können Sie eine defaultIfNull, oder coalesce Funktion schreiben, die den Code noch prägnanter machen kann. Apache Commons Lang includes a defaultIfNull function.

Einige Sprachen enthalten einen Operator ||=, der das übliche Idiom für Standardwerte in diesen Sprachen ist.

+0

Verwendung des bedingten Operators in C "nicht vermeiden Kontrollstrukturen". Sehen Sie sich die Compiler-Ausgabe an. –

+0

Ich habe meine Compiler-Ausgabe angeschaut. http://www.theeggeadventure.com/wikimedia/index.php/Ternary_Operator_in_C Stellt sich heraus, der GCC-C-Compiler kann identische Assembly erstellen, unabhängig davon, ob Sie die ternäre oder If/then/else-Struktur verwenden. – brianegge

+1

Das ist richtig, der Compiler kann branchfreien Code generieren, wenn es möglich ist, entweder für eine 'if'-Anweisung oder den bedingten Operator. Wenn dies nicht möglich ist, wird eine der Anweisungen mit Verzweigungen generiert. Ich beziehe mich auf Ihre Implikation, dass "das Vermeiden von Kontrollstrukturen" dasselbe ist wie "den bedingten Operator verwenden". –

1

In Ihrem Fall würde ich die "klassische" Implementierung bevorzugen, denn für mich ist es schneller zu verstehen, dass Sie nur eine neue Farbe verwenden möchten, wenn die Person eine bevorzugte Farbe hat.

ich es manchmal in Methode aufruft, wenn ich NPE vermeiden wollen, aber ich in der Regel diese hässlichen Teile des Codes in einer der nächsten Refactorings elimate;)

4

Ablesbarkeit, ein leichteres Verständnis usw. sind die gleichen in dieser Fall (ich meine, komm schon ...). Ich mag die Duplizierung und scheinbare Selbstzuweisung im ersten Beispiel nicht; es würde zu etwas wie übersetzen:

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

das ist ein bisschen dumm.

Ich würde normalerweise die zweite in einer Zeile schreiben, aber das ist eine Frage der individuellen Phantasie resp. Codierstil Richtlinien:

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

EDIT (Ich bin jetzt mehr opinionated als 8 Jahren)

Da Sie für Best Practices suchen:

// 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); 
    } 
} 
+0

Oder auch wenn (color! = Null) messageColour = color; –

Verwandte Themen