2009-11-29 30 views
11

¿Es esta una práctica de codificación aceptable?Usando operador ternario con 4 expresiones

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

o estoy mejor ir con el clásico ...

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

Es formalmente la operator__ __conditional, [ según el JLS] (http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.25). Técnicamente, podría haber otros operadores ternarios, al igual que existen numerosos operadores binarios, aunque Java actualmente no tiene ninguno. – Pops

Respuesta

24

El uso del operador?: Debe limitarse para que el código sea más legible. Un ejemplo clásico:

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

En este caso, el código sería menos legible si se rompió para arriba en cerca de 5 líneas if/else.

Generalmente pongo corchetes alrededor de todo el operador para que cuando lo lea lo analice mentalmente como un valor único.

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

Otra variante es

messageColor = color || messageColor; 

que en algunos idiomas se evaluará como "de color, a no ser que el color se evalúa como 'falsa', en la que el valor caso de messageColor. En mi opinión, esto se debe evitar puede confundir a la gente.

lo más importante es ser constante para que la próxima persona que lee el código (incluso si eres tú) tiene sobrecarga cognitiva mínimo.

+0

gran ejemplo. Fácil de comprender. –

0

parece estar bien para mí (yo uso operador ternario de Python mucho), pero este tipo de cuestiones de estilo es generalmente muy subjetivo . Si el proyecto tiene un documento de estilo de codificación, es posible que desee verificarlo.

1

Prefiero el segundo porque expresa más claramente lo que quieres decir: solo quieres cambiar el color si no es nulo. El primer método no lo hace tan claro.

2

El uso del operador ternario suele ser un problema delicado, junto con otros estándares de codificación. Probablemente su uso esté mejor determinado por los estándares de codificación en su sitio.

Sin embargo, en esta situación específica, definitivamente recomendaría la segunda opción; no solo es más claro, sino que el uso del operador ternario es totalmente innecesario aquí. No es necesario volver a asignar messageColor a sí mismo, por lo que la única función del operador ternario en esta situación particular es la ocultación del código.

1

Los operadores ternarios suelen ser objeto de abuso ya que el código que producen parece inteligente y compacto.

De hecho, hacen que el código sea menos legible y más propenso a errores. Siempre que sea posible, es recomendable utilizar la versión más larga de

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

En lugar de una sintaxis ternaria.

+0

no es completamente cierto: los operadores ternarios pueden hacer que el código sea más legible (no siempre, estoy de acuerdo) –

2

El operador ternario es más común entre los programadores C. En C, si evita las estructuras de control, a menudo puede obtener un mejor canalización, ya que no existe una predicción de bifurcación que salga mal. Dudo que veas diferencia de rendimiento en Java, y el patrón if-null-then-assign es mucho más común que el ternario. Sin embargo, si mantiene una base de código existente, generalmente es mejor mantenerse coherente con el código existente.

Si usted se encuentra haciendo esto mucho, se puede escribir una función defaultIfNull, firstNonNull o coalesce que puede hacer que el código aún más concisa. Apache Commons Lang includes a defaultIfNull function.

Algunos idiomas incluyen un operador ||=, que es la expresión habitual para valores predeterminados en esos idiomas.

+0

El uso del operador condicional en C no "evita las estructuras de control". Eche un vistazo a la salida de su compilador. –

+0

Miré la salida de mi compilador. http://www.theeggeadventure.com/wikimedia/index.php/Ternary_Operator_in_C Resulta que el compilador gcc C puede crear un ensamblaje idéntico independientemente de si usa la estructura ternaria o si/entonces/else. – brianegge

+1

Correcto, el compilador puede generar código sin ramificación si puede, ya sea para una instrucción 'if' o para el operador condicional. Si no puede, cualquiera de las declaraciones se generará con ramas. Me refiero a su implicación de que "evitar las estructuras de control" es lo mismo que "usar el operador condicional". –

1

En su caso, preferiría la implementación 'clásica', porque para mí es más rápido de entender, solo quiere usar un nuevo color si la persona tiene uno preferido.

veces lo uso en el método de llamadas si quiero evitar NPE, pero por lo general elimate esos feos trozos de código en uno de los próximos refactorizaciones;)

4

legibilidad, facilidad de comprensión, etc., son los mismos en este caso (Quiero decir, vamos ...). No me gusta la duplicación y la auto asignación aparente en el primer ejemplo; se traduciría a algo así como:

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

que es un poco estúpido.

Normalmente escribo el segundo en una línea, pero esa es una cuestión de resp individual de lujo. codificación de las guías de estilo:

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

EDITAR (soy ahora más obstinado que hace 8 años)

Desde que busca las mejores prácticas:

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

O incluso si (color! = Nulo) messageColour = color; –

Cuestiones relacionadas