Длинный список если операторы в Java

Это будет, вероятно, работать на большое количество лет, но в конечном счете Вы перейдете к сути дела, где необходимо поддержать старые аппаратные средства, выполнив старую, unpatchable ОС, для выполнения программного обеспечения. Между тем Вы пропускаете всю новую платформу и положительных героев языка, которые разрабатываются. В конечном счете у Вас будет потребность зафиксировать что-то или добавить что-то, что не возможно в Вашей среде, и затем Вы добираетесь для оплаты цельный счет для накопленного технического долга.

Мое взятие: необходимо уже работать над обновлением более новой платформы или замены для приложения. Мое предпочтение должно почти всегда делать это, прежде чем я буду вынужден к обстоятельствами.

100
задан Punit Vora 4 October 2011 в 19:38
поделиться

13 ответов

с использованием шаблона команды :

public interface Command {
     void exec();
}

public class CommandA() implements Command {

     void exec() {
          // ... 
     }
}

// etc etc

затем создайте объект Map и заполните его командой экземпляры:

commandMap.put("A", new CommandA());
commandMap.put("B", new CommandB());

, тогда вы можете заменить цепочку if / else if на:

commandMap.get(value).exec();

EDIT

, вы также можете добавить специальные команды, такие как UnknownCommand или NullCommand , но вам понадобится CommandMap , которая обрабатывает эти угловые случаи, чтобы минимизировать проверки клиентов.

169
ответ дан 24 November 2019 в 04:51
поделиться

Если он выполняет много действий, тогда будет много кода, от этого никуда не деться. Просто упростите отслеживание, дайте переменным понятные имена, комментарии тоже могут помочь ...

-1
ответ дан 24 November 2019 в 04:51
поделиться

Я не уверен, есть ли у вас какое-либо совпадение между поведением ваших различных команд, но вы также можете взглянуть на шаблон Chain Of Responsibility , который может обеспечить большую гибкость, позволяя нескольким командам обрабатывать некоторые входные значения.

0
ответ дан 24 November 2019 в 04:51
поделиться

если бы можно было иметь массив процедур (то, что вы назвали командами), которые были бы полезны…

но вы могли бы написать программу для написания вашего кода. Все очень систематично если (значение = 'A') commandA (); еще если(........................ и т. д.

0
ответ дан 24 November 2019 в 04:51
поделиться

Просто используйте HashMap, как описано здесь:

0
ответ дан 24 November 2019 в 04:51
поделиться

если у вас есть несколько составных операторов if, то это шаблон для использования механизма правил . См., Например, JBOSS Drools .

1
ответ дан 24 November 2019 в 04:51
поделиться

Я обычно пытаюсь решить это таким образом:

public enum Command {

A {void exec() {
     doCommandA();
}},

B {void exec() {
    doCommandB();
}};

abstract void exec();
 }

это имеет много преимуществ:

1) невозможно добавить перечисление без реализации exec. так что вы не пропустите A.

2) вам даже не нужно будет добавлять его к какой-либо карте команд, поэтому нет шаблонного кода для построения карты. просто абстрактный метод и его реализации. (который, возможно, также является шаблонным, но он не станет короче ..)

3) вы сэкономите любые потраченные впустую циклы процессора, просмотрев длинный список if или вычислив хэш-коды и выполнив поиск.

edit: если у вас нет перечислений, но есть строки в качестве источника, просто используйте Command.valueOf (mystr) .exec () для вызова метода exec. обратите внимание, что вы должны использовать модификатор public для exec, если хотите вызвать его из другого пакета.

2
ответ дан 24 November 2019 в 04:51
поделиться

Даже если я считаю, что подход с использованием шаблонов команд больше ориентирован на лучшие практики и удобен в обслуживании в долгосрочной перспективе, вот вам один вариант:

org.apache.commons.beanutils. MethodUtils.invokeMethod (this, "doCommand" + значение, null);

3
ответ дан 24 November 2019 в 04:51
поделиться

Я предлагаю создать объекты команд и поместить их в хэш-карту, используя строку в качестве ключа.

5
ответ дан 24 November 2019 в 04:51
поделиться

Мое предложение было бы своего рода облегченной комбинацией перечисления и объекта Command. Это идиома, рекомендованная Джошуа Блохом в правиле 30 Эффективной Java.

public enum Command{
  A{public void doCommand(){
      // Implementation for A
    }
  },
  B{public void doCommand(){
      // Implementation for B
    }
  },
  C{public void doCommand(){
      // Implementation for C
    }
  };
  public abstract void doCommand();
}

Конечно, вы можете передавать параметры в doCommand или иметь возвращаемые типы.

Это решение может быть не совсем подходящим, если реализация doCommand на самом деле не подходит » fit »к типу enum, который - как обычно, когда приходится идти на компромисс - немного нечеткий.

12
ответ дан 24 November 2019 в 04:51
поделиться

Имейте перечисление команд:

public enum Commands { A, B, C; }
...

Command command = Commands.valueOf(value);

switch (command) {
    case A: doCommandA(); break;
    case B: doCommandB(); break;
    case C: doCommandC(); break;
}

Если у вас больше, чем несколько команд, попробуйте использовать шаблон Command, как указано в другом месте (хотя вы можете сохранить перечисление и встроить вызов в реализующий класс в перечислении вместо использования HashMap). См. Пример ответа Андреаса или Йенса на этот вопрос.

7
ответ дан 24 November 2019 в 04:51
поделиться

Вам, вероятно, лучше всего использовать карту команд.

Но если у вас есть набор из них, вы в конечном итоге столкнетесь с множеством карт. Тогда стоит взглянуть на то, чтобы сделать это с помощью Enums.

Вы можете сделать это с помощью Enum без использования переключателей (вам, вероятно, не нужны геттеры в примере), если вы добавите метод в Enum для разрешения для " ценность". Затем вы можете просто сделать:

Обновление: добавлена ​​статическая карта, чтобы избежать итераций при каждом вызове. Бесстыдно ущемленный из этот ответ .

Commands.getCommand(value).exec();

public interface Command {
    void exec();
}

public enum Commands {
    A("foo", new Command(){public void exec(){
        System.out.println(A.getValue());
    }}),
    B("bar", new Command(){public void exec(){
        System.out.println(B.getValue());
    }}),
    C("barry", new Command(){public void exec(){
        System.out.println(C.getValue());
    }});

    private String value;
    private Command command;
    private static Map<String, Commands> commandsMap;

    static {
        commandsMap = new HashMap<String, Commands>();
        for (Commands c : Commands.values()) {
            commandsMap.put(c.getValue(), c);    
        }
    }

    Commands(String value, Command command) {
        this.value= value;
        this.command = command;
    }

    public String getValue() {
        return value;
    }

    public Command getCommand() {
        return command;
    }

    public static Command getCommand(String value) {
        if(!commandsMap.containsKey(value)) {
            throw new RuntimeException("value not found:" + value);
        }
        return commandsMap.get(value).getCommand();
    }
}
2
ответ дан 24 November 2019 в 04:51
поделиться

If the context of your code have internet access, you can try to use the Google API for language detection. http://code.google.com/apis/ajaxlanguage/documentation/

var text = "¿Dónde está el baño?";
google.language.detect(text, function(result) {
  if (!result.error) {
    var language = 'unknown';
    for (l in google.language.Languages) {
      if (google.language.Languages[l] == result.language) {
        language = l;
        break;
      }
    }
    var container = document.getElementById("detection");
    container.innerHTML = text + " is: " + language + "";
  }
});

И, поскольку вы используете C #, ознакомьтесь с этой статьей о том, как вызывать API из C #. .

ОБНОВЛЕНИЕ:

У вас тоже может быть массив

Command[] commands =
{
  new CommandA(), new CommandB(), new CommandC(), ...
}

Затем вы можете выполнить команду по индексу

commands[7].exec();

Плагиат из DFA, но имея абстрактный базовый класс вместо интерфейса. Обратите внимание на cmdKey, который будет использоваться позже. По опыту я понимаю, что часто команда оборудования также имеет подкоманды.

abstract public class Command()
{
  abstract public byte exec(String subCmd);
  public String cmdKey;
  public String subCmd;
}

Создайте свои команды таким образом,

public class CommandA
extends Command
{
  public CommandA(String subCmd)
  {
    this.cmdKey = "A";
    this.subCmd = subCmd;
  }

  public byte exec()
  {
    sendWhatever(...);
    byte status = receiveWhatever(...);
    return status;
  }
}

Затем вы можете расширить общий HashMap или HashTable, предоставив функцию отсасывания пары ключ-значение:

public class CommandHash<String, Command>
extends HashMap<String, Command>
(
  public CommandHash<String, Command>(Command[] commands)
  {
    this.commandSucker(Command[] commands);
  }
  public commandSucker(Command[] commands)
  {
    for(Command cmd : commands)
    {
      this.put(cmd.cmdKey, cmd);
    }
  }
}

Затем создайте свою команду store:

CommandHash commands =
  new CommandHash(
  {
    new CommandA("asdf"),
    new CommandA("qwerty"),
    new CommandB(null),
    new CommandC("hello dolly"),
    ...
  });

Теперь вы можете отправлять элементы управления объективно

commands.get("A").exec();
commands.get(condition).exec();
7
ответ дан 24 November 2019 в 04:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: