2011-01-11 7 views
5

estoy usando Java 6.caso interruptor de Java - por defecto vs enumeración explícita

Supongamos que tengo una enumeración con 6 valores, ordenado de A a F. Sobre 4 de los valores se manejaron de la misma. Podría escribirlo así.

switch (whichType) { 
    case A: 
    case B: 
    case C: 
    case D: 
     return task(); 
    case E: 
     return someothertask(); 
    case F: 
     return anothersomeothertask(); 
} 

O como este.

switch (whichType) { 
    case E: 
     return someothertask(); 
    case F: 
     return anothersomeothertask(); 
    default: 
     return task(); 
} 

Los valores nulos nunca llegarán a este modificador.

En términos de concisión y claridad, el segundo enfoque es mejor. En términos de ser explícito, creo que el primer enfoque es mejor.

¿Hay otros pros/contras de cada enfoque?

Además, esta simple pregunta corre el riesgo de ser un duplicado, pero lo intenté y no pude encontrarlo en ninguna otra parte. Me disculpo si no lo he buscado lo suficientemente bien.

+4

agregue un método abstracto a su clase enum? – Ron

+2

Solo para el registro: puede poner una sección 'default' en la parte superior, en el centro o en cualquier otro lugar dentro del' switch'; no tiene que estar en la parte inferior. –

+0

@ ChrisJester-Young Pero algunos analizadores de código estático prohíben poner valores predeterminados en posiciones que no sean inferiores. – mjafari

Respuesta

7

Ambos están bien si esa enumeración se fija de manera absoluta y positiva en seis valores para siempre. De lo contrario, piense en qué podría ser un séptimo valor posible para la enumeración. Si E y F son los dos únicos valores atípicos posibles con respecto a esta lógica switch y cualquier otro valor caería en el mismo cubo que de A a D, adelante y utilice el default. De lo contrario, es más seguro tener un case por valor.

3

Supongamos que alguien agrega un valor a la enumeración?

En algún código que tengo, hay este tipo de construcción:

switch(mediaType) { 
    case typeA: 
    case typeB: 
    case typeC: 
     DoGeneric(); 
     break; 
    case TypeD: 
     DoSpecial(); 
     break; 
} 

Y la razón de ello es por lo que si alguien añade otra posibilidad de la enumeración, que no se compilará hasta que' Vemos los lugares donde se usa la enumeración y decidimos qué hacer en ese momento. No hay posibilidad de perder uno y tener un error difícil de localizar.

+0

+1 para el caso de agregar un nuevo elemento a la enumeración. – unholysampler

+4

Ummm ... ese código ** compilará ** después de que alguien agregue 'typeE'. –

+0

@Stephen C: Dependiendo del idioma, sí podría (no desarrollo en Java). Pero de esta manera, las herramientas de estilo de código pueden retomarlo, mientras que con 'default' es imposible saber si se ha olvidado o no. –

2

Bueno, con respecto a la legibilidad, yo diría que el segundo puede no ser más claro. Por ejemplo, su caso común ocurre DESPUÉS de sus casos especiales.

Sin embargo, el problema real que veo aquí es que los dos códigos no son realmente equivalentes. En el primer caso, tiene seis casos explícitos. En el segundo, tiene dos casos explícitos y un caso predeterminado. Esto significa que, si su código tiene algún tipo de error en el que recibe un caso que no esperaba, el caso predeterminado seguirá funcionando en el segundo (y task() seguirá ejecutándose). Como resultado, esto es fundamentalmente diferente de su primer código.

Aparte de eso (decidir qué instrucción de cambio es la correcta), yo diría que se quede con la que le parezca mejor. A mí personalmente me gusta el primero (porque es explícito y deja espacio para un caso predeterminado si es necesario), pero tendrá que decidir en función de sus preferencias o los estándares de desarrollo de su compañía/equipo.

0

Si está escribiendo un escenario de negocios, y espera que el código siga vivo y se mantenga (por otra persona) en los próximos años, vaya a la opción 1. No hay nada de malo en la opción 2, es corta y claro, pero cuando hablamos de mantenibilidad, creo que la opción 1 gana, especialmente si los casos están relacionados con alguna lógica comercial. Será mucho más fácil para el ingeniero de mantenimiento leerlo.

2

Tiendo a utilizar valor predeterminado para detectar nuevas enumeraciones agregadas después de la implementación inicial. Esto no produce un error en tiempo de compilación, que prefiero, pero generalmente no pasa la prueba de humo.

switch (whichType) { 
    case A: 
    case B: 
    case C: 
    case D: 
     return task(); 
    case E: 
     return someothertask(); 
    case F: 
     return anothersomeothertask(); 
    default: 
     throw new IllegalArgumentException("Encountered unknown type: " + whichType.name()); 
} 
Cuestiones relacionadas