альтернатива если заявление в Java - PullRequest
6 голосов
/ 25 октября 2009

Мне любопытно увидеть любые альтернативы обычным операторам if, таким как

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

так, как вы видите все, если операторы являются отдельными и никакие другие условия. Обратите внимание, что X Y Z - полностью отдельные условия, поэтому переключатель не подходит.

Ответы [ 10 ]

27 голосов
/ 25 октября 2009

Один «истинно объектно-ориентированный» ответ будет состоять в том, чтобы определить интерфейс для «Rule» (с методами condition () и action ()), создать 3 реализации, поместить их в коллекцию, а затем просто перебрать их как в:

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

Это имеет больше смысла, если у вас есть 300 правил / условий, а не только 3.

В Java8 вы можете сделать это вместо этого, если правила интенсивно используют процессор:

rules.parallelStream().filter(Rule::condition).forEach(Rule::action);
8 голосов
/ 25 октября 2009

Краткий ответ - да.

Есть несколько раз, когда вы можете избежать использования if для условного выделения и ветвления всего вместе. И у них есть моменты уместности.

  1. Полиморфизм, когда поведение зависит от начальных значений
  2. Ссылочное присвоение, когда вы знаете возможные начальные значения, и они имеют соотношение 1 к 1 с возвращаемыми значениями. Списки лучше, чем массивы для этого, но ...

    // 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. Ссылочное ветвление, когда вы знаете возможные начальные значения, и они имеют соотношение 1: 1 к используемой функции / ветви. (пример не 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. Прямое логическое присваивание.

    Мы ненавидим:

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

    Должно быть:

    b = thisCondition;

5 голосов
/ 25 октября 2009

Альтернативами if-else в Java являются оператор switch и условный троичный оператор (?: ), ни один из которых не выполняет в точности то, что вы запрашиваете (обрабатываете просто) if без else). Код, который вы разместили, на мой взгляд, лучший способ сделать это.

3 голосов
/ 25 октября 2009

Использовать полиморфизм.

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();
     }
}

If не полностью устранено, но перемещено в SomethingDoerFactory. Это решение применимо не во всех случаях, но в некоторых из них это очень хорошая альтернатива множественным ifs.

Вот хороший разговор об этом:
http://misko.hevery.com/2008/12/08/clean-code-talks-inheritance-polymorphism-testing/

3 голосов
/ 25 октября 2009

это самое простое, удобочитаемое, но эффективное решение. Я был бы удивлен, увидев здесь эффективные альтернативы.

EDIT

Вы можете попробовать применить метод извлечения несколько раз:

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

где методы определены:

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

    // do 'a'
}
0 голосов
/ 28 сентября 2017

Это действительно зависит от контекста ... но да, если-еще только один из управления потоком оператор в Java: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/flow.html

0 голосов
/ 10 марта 2013

Как насчет ... myAnimator (вещь, позиция, скорость | computeSpeed ​​());

если скорость === не определено то вычислит скорость ... Я думаю.

0 голосов
/ 25 октября 2009

Звучит как идеальный случай для использования закрытия . Но для этого вам нужно Groovy или что-то подобное.

0 голосов
/ 25 октября 2009

Вам понадобятся эти операторы if где-нибудь.

Они могут быть преобразованы в другие методы, чтобы сохранить настоящий метод в чистоте, как предлагали другие. Если вам необходимо повторно использовать тот же набор операторов if в нескольких местах, может стать возможным, используя Pattern Decorator .

0 голосов
/ 25 октября 2009

это действительно зависит от того, что x, y, z и a, b, c Иногда, если заявления более подходят. Иногда полиморфизм более подходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...