2016-07-12 2 views
0

Я ищу, чтобы узнать, как адаптировать существующую реализацию шаблона команды к JAVA 8 lambdas.Использование lambdas в шаблоне команд

@FunctionalInterface 
public interface Command { 

    public void execute(final Vehicle vehicle); 
} 

public class LeftCommand implements Command { 

public void execute(final Vehicle vehicle){ 
    vehicle.turnLeft(); 
} 

} 

public class RightCommand implements Command { 

public void execute(final Vehicle vehicle){ 
    vehicle.turnRight(); 
} 

} 

У меня есть класс VehicleManager который вызывает processValue, который выглядит для создания команды на основе строки L или R, который передается к нему как InputValue

processValues(Vehicle vehicle, String inputValue){ 
if("L".equals(inputValue){ 
    //create left command here 
    Command cmd = (vehicle) -> vehicle.turnLeft(); //ERROR 
    Command cmd =() -> vehicle.turnLeft(); //ERROR,expects 1 parameter vehicle to be passed 
}else{ 
// create right command here 
    Command cmd = (vehicle) -> vehicle.turnRight(); //ERROR 
} 
} 

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

  1. Не могли бы вы посоветовать мне, как я могу создавать левые и правые экземпляры команд здесь, используя лямбды?

  2. Если я могу успешно использовать лямбда выше, то могу ли я покончить с классами LeftCommand и RightCommand?

(Я проверил множество ссылок на google, но я не мог заставить это работать).

ДОБАВЛЕННОЙ НАСТОЯЩЕГО ПОСТ Некоторые комментарии,

private void processValues(String line, Vehicle vehicle) { 
    List<Command> commands = new ArrayList<>(); 
    for(char c: line.toCharArray()){ 
     if(LEFT.equals(c)){ 
      commands.add(()-> vehicle.turnLeft()); 
     }else if(RIGHT.equals(c)){ 
      commands.add(()-> vehicle.turnRight()); 
     }else if(MOVE.equals(c)){ 
      commands.add(()-> rover.moveForward()); 
     } 
    } 
    commands.forEach((c) -> c.execute()); 
} 

Правильно ли это?

+3

Вещь между скобками '(vehicle)' - это новое объявление переменной, которое является параметром для метода целевого функционального интерфейса. Поскольку переменная с этим именем уже существует в этом контексте, вы не можете использовать ее в списке параметров выражения лямбда. Используйте что-то другое, например 'v'. –

+1

Ваш метод processValues ​​запутан: вам не нужен конкретный автомобиль для создания команды ... Таким образом, команда может быть чем-то вроде: 'Command cmd = v -> v.turnLeft();' или 'Command cmd = Vehicle :: turnLeft'. Затем вы можете применить его к определенному транспортному средству: 'cmd.execute (vehicle);' ... – assylias

+0

@assylias Я создал что-то вроде этого. Это верно. Пожалуйста, проверьте последний раздел, который я добавил в свой пост. – megan

ответ

1

Использование lambdas или ссылок на методы в Command Pattern сделает ваши RightCommand и LeftCommand классы бесполезными.

В первом примере, следует применять к чему-то вроде этого:

private void processValues(Vehicle vehicle, String inputValue) { 
    Command command; 
    if ("Left".equals(inputValue)) { 
    command = v -> v.turnLeft(); // <- With lambda expresion 
    } else { 
    command = Vehicle::turnRight; // <- With method reference 
    } 
    command.execute(vehicle); 
} 

Лучшее объяснение можно найти в "Using the command pattern with lambda expressions".