Вопрос по conditional, java, switch-statement, polymorphism, design-patterns – проблема с полиморфизмом победить эти утверждения переключения / case

5

Продолжая на предыдущих вопросах (Вот, а такжеВот), Я реализовал базовый шаблон команд, создал свои классы команд и закодировал их в интерфейсе, поэтому при использовании любой команды вызыватьexecute() метод.

Тем не менее, я все еще нахожу себя неспособным встряхнуть эти утверждения случая: я читаю каждый символ из строки мастера / решения, которая состоит из случайных повторяющихся символов A, B, C или D, а затем извлекаю соответствующую реализацию команды из карты и вызовите ее метод execute.

Мой дизайн был таким:

public interface Command {
    void execute();
}

public class CommandA implements Command{
  //implements execute() method
}

private Map myMap= new HashMap();
myMap.put("A", new CommandA);
myMap.put("B", new CommandB);
myMap.put("C", new CommandC);
myMap.put("D", new CommandD);

Но затем, когда я читаю каждую инструкцию, я снова вынужден прибегать к утверждениям:

switch(instructionFromString){
case 'A':{myMap.get("A").execute(); break;}
case 'B':{myMap.get("B").execute(); break;}
case 'C':{myMap.get("C").execute(); break;}
case 'D':{myMap.get("D").execute(); break;}

Очевидно, что где-то по пути мне удалось победить преимущество полиморфизма перед заявлениями по делу.

Может ли это быть такая структура данных, которую я выбрал для хранения своих команд? Это может быть постоянная структура данных, из которой можно просто извлекать эти команды.

Еще одна вещь, которая приходит на ум - это название ключа / значения, которое я использовал на своей карте. Как я пытался концептуально связать каждую сохраненную команду с соответствующей инструкцией? т.е. выполнение команды "А", хранится на карте с ключом «А» поэтому он может соответствовать соответствующей инструкции «А»? Это кажется мне немного маловероятным, хотя.

Буду очень признателен за любую подсказку или дальнейший совет относительно моего следующего шага, чтобы раз и навсегда удалить эти заявления случая. Спасибо заранее

Ваш Ответ

3   ответа
14

Я могу что-то здесь упустить, но вместоswitch Скажите, чтоне так с

((Command)myMap.get(instructionFromString)).execute();

Если инструкцияFromString являетсяcharпреобразовать его вString перед поиском карты, иначе используйтеCharacter ключи на вашей карте.

Кроме того, если вы используете общую карту Java 5, то вы можете удалить приведение кCommand, Очищенная версия будет:

private Map myMap = new HashMap();
myMap.put('A', new CommandA());
myMap.put('B', new CommandB());
myMap.put('C', new CommandC());
myMap.put('D', new CommandD());

с последующим:

char instructionFromString = ....
myMap.get(instructionFromString).execute();
@skaffman: Спасибо, довольно элегантно. Можно'не верю, что пропустил это! denchr
Также используйте дженерики. Дон»т использовать сырые коллекции user44242
+1 за ответ япроцитировать»и расширить на. KLE
@skaffman: Извините. Мне удалось как-то прочитать пример кода, но пропустил текст выше и ниже. Dirk
0

С простой картой все может стать неприятным, так как выповторно использовать тот же экземплярCommandA снова и снова

Хороший способ инкапсулировать такое поведение было бызавод:

public class CommandFactory
{
    public Command CreateCommand(String instruction)
    {
        if (instruction.equals("A"))
            return new CommandA();
        else if ...
    }
}

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

public class CommandFactory
{
    private Map commands = new HashMap();

    public void RegisterCommand(String instruction, Command commandTemplate)
    {
        commands.put(instruction, commandTemplate);
    }

    public Command CreateCommand(String instruction)
    {
        return commands.get(instruction).clone();
    }
}

Как вы могли заметить, выпридется реализовать поведение клона вCommands, что может занять много времени.

0

Мне нравится скаффманответ. Я только хочу добавить еще:

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

  • В общем случае, это гораздо меньше, чтобы напечатать. Это устраняет ошибки.
  • Когда имя отличается, вы все равно настраиваете карту для этого конкретного случая.

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

  • Аннотации для класса, который задает имя команды (по умолчанию равно названию класса).
  • Конфигурация Spring уже является такой большой картой и напрямую доставляет соответствующий объект со многими доступными сервисами.
  • Перечисления Java также естественным образом ассоциируют имя с объектом. Более того, они позволяют вам выполнять проверку завершения и времени компиляции в вашей IDE, а такжепоиск ссылок " и другие вкусности.
@KLE: Спасибо! Там тоже есть полезные советы. denchr

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