2009-10-25 49 views
5

tengo curiosidad de ver cualquier alternativa (s) al regular si las declaraciones tales comoalternativa a la sentencia if en Java

if(x) 
    do a; 
if(y) 
    do b; 
if(z) 
    do c; 

con el fin de que se ve todo si las declaraciones son independientes y ninguna condición else. Tenga en cuenta que X Y Z son condiciones totalmente independientes, por lo que el cambio no cabría.

+4

Mientras que la curiosidad puede ser divertido ... ¿Por qué querría una alternativa a si, especialmente cuando una condición es que el interruptor no encaja? Como si Java ya no estuviera lo suficientemente hinchado ... – ty812

+0

o lo que estás intentando hacer es tonto (¡si es genial!), O necesitas dar más información. Me imagino una situación en la que el código como este podría manejarse con un patrón de mensajes u otra cosa que sea interesante (siempre que su situación no sea tan simple como la explicó). – twolfe18

+0

¿Qué espera que brinde esta alternativa que el código presentado no puede? (menos caracteres, más legibilidad?) – Zed

Respuesta

24

Un "objeto verdaderamente orientado" respuesta sería definir una interfaz para la "Regla" (con la condición() y la acción() métodos), cree 3 implementaciones, meterlas en una colección, y luego simplemente iterar a través de ellos de forma genérica como en:

 
List<Rule> rules = .... ; // your 3 rules initialized here somehow 
for(Rule r : rules) { 
    if(r.condition()) { 
    r.action(); 
    } 
} 

Esto tiene mucho más sentido si usted tiene 300 reglas/condiciones en lugar de sólo 3.

En Java8, puede que desee hacer esto en su lugar, si las reglas son intensivo de la CPU:

rules.parallelStream().filter(r -> r.condition()).forEach(r -> r.action()); 
+0

Puede usar un Mapa para el tiempo O (1), en lugar de O (n). –

+0

Un mapa no funcionará aquí, porque la condición es única para cada implementación de la regla. El mapa requiere una clave real, no algún código oculto en un método invocable. –

3

esta es la solución más simple, legible pero eficaz. Me sorprendería ver alternativas efectivas aquí.

EDITAR

se puede tratar de aplicar método de extracto de varias veces:

doAIfX(); 
doBIfY(); 
doCifZ(); 

donde los métodos se definen por:

void doAIfX() { 
    if (!X) { 
     return; 
    } 

    // do 'a' 
} 
+4

Sin voto negativo, pero esto no me parece correcto. – ChaosPandion

+0

Lo hago en firmware para un dispositivo que puede tener muchas opciones diferentes habilitadas o deshabilitadas. Prefiero tener mis principales() llamadas cosas como doFooIfEnabled() que abarrotarlo con un montón de ifs y #ifdefs. –

+1

Al igual que cualquier patrón, hay momentos en los que debe usarse y otros en los que no debería usarse. – bdonlan

0

que realmente depende de lo que x, y, z y a, b, c son. A veces, si las declaraciones son más adecuadas. Algunas veces el polimorfismo es más adecuado.

5

Las alternativas a if-else en Java son la sentencia switch y el conditional ternary (:?) del operador, ninguno de los cuales hacen exactamente lo que estás pidiendo (manejar sólo una if sin else). El código que publicaste es la mejor manera de hacerlo, en mi opinión.

2

Usa polimorfismo.

interface SomethingDoer { 
    public void doSomething(); 
} 

class ADoer implements SomethingDoer { ... } 
class BDoer implements SomethingDoer { ... } 
class CDoer implements SomethingDoer { ... } 

public class Main { 
    public static void main (String[] args) { 
      SomethingDoer doer = new SomethingDoerFactory(args).getDoer(); 
      doer.doSomething(); 
    } 
} 

El if no se elimina por completo, pero se mueve a SomethingDoerFactory. Esta solución no es aplicable en todos los casos, pero en algunos de ellos es una muy buena alternativa a múltiples ifs.

Aquí es un bonito hablar de ello:
http://misko.hevery.com/2008/12/08/clean-code-talks-inheritance-polymorphism-testing/

+1

¿Algún comentario sobre por qué bajas tu voto? ¿No es una alternativa? ¿O no es lo suficientemente bueno para ser mencionado? – artemb

+3

Solo consideraría una solución polimórfica si mi condicional ya estaba basado en ** tipo **. No crearía una jerarquía de clases completa solo para reemplazar 'if (x) do a;' –

+2

si en muchos casos esto tiene sentido. ver http://www.youtube.com/watch?v=4F72VULWFvc - google tech talks. (The Clean Code Talks - Herencia, Polimorfismo y Pruebas) considero erróneo el voto negativo. –

7

La respuesta corta es sí.

Hay algunas ocasiones en que puede evitar utilizarlas si se trata de evluation condicional y de ramificación juntas. Y tienen momentos de adecuación.

  1. polimorfismo, cuando el comportamiento depende de los valores iniciales
  2. Asignación Referrenced, cuando se conocen los posibles valores iniciales y tienen 1 a 1 correlación con los valores de retorno.Las listas son mejores que las matrices para esto, pero ...

    // Example: 
    if (a==1) { b=2; } 
    if (a==2) { b=17; } 
    
    // Becomes 
    int fx(2); // our array of answers 
    fx[0] = 2; 
    fx[1] = 17; 
    b = fx[ a - 1 ]; 
    
  3. Referrenced ramificación, cuando se conocen los posibles valores iniciales y tienen 1 a 1 correlación con la función/rama de usar . (Ejemplo no Java)

    // Example: 
    if (a==1) { doSomething1(); } 
    if (a==2) { doSomething2(); } 
    
    // Becomes 
    function * fx(2); // our array or better still, list of functions 
    fx[0] = &doSomething1; 
    fx[1] = &doSomething2; 
    `fx[ a - 1 ](); ` 
    
  4. asignación boolean directa.

    No nos gusta:

    if (thisCondition == true) { 
        b = true; 
    } else { 
        b = false; 
    } 
    

    debe ser:

    b = thisCondition;

+0

Votación abajo para publicar el código C para una pregunta de Java! –

0

Usted necesita tener estos si los estados parte.

Se pueden refabricar en otros métodos para mantener el método presente limpio, como otros han sugerido. Si necesita volver a utilizar este mismo establecer de sentencias if en varios lugares, es posible usar Decorator Pattern.

0

Switch quizás?

No puedo pensar por qué querrías reemplazarlo.

0

Parece una carcasa perfecta para usar cierre. Pero para eso necesita groovy o algo similar.

0

¿Qué tal ... myAnimator (cosa, pos, velocidad | computeSpeed ​​());

if speed === undefined se computeSpeed ​​... Creo.

Cuestiones relacionadas