Статьи

Применен шаблон проектирования команд

Всем привет!

Сегодня я поделюсь с вами действительно отличным дизайном программирования. У него много употреблений, и это один из моих любимых. Команда шаблона degin программирования имеет огромное количество вариантов использования. В этом посте мы увидим, как реализовать что-то из реального мира.

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

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

Шаблон команд UML

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

command_action

Объяснение деталей дизайна программирования

Наш клиент — владелец Ferrari (FerrariCleint). У него есть CarKey. CarKey имеет общий MicroShip (Involker), который можно настроить с помощью команд. Команды (OpenDoorCommand) сами должны выполнить действие (DoorAction). CarKey может конфигурировать команды do и undo. NullObjectCommand принадлежит шаблону проектирования пустых объектов, и он также будет использоваться здесь. Давайте посмотрим в коде детали реализации сейчас.

Командование и MicroShip

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public interface Command {
    void execute();
}
public class MicroChip {
    protected Command[] onCommands;
    protected Command[] offCommands;
    public MicroChip(int commandQuantity) {
        onCommands =  new Command[commandQuantity];
        offCommands = new Command[commandQuantity];
        Command nullObjecCommand =  new NullObjectCommand();
        for (int i = 0; i < commandQuantity; i++) {
            onCommands[i]=nullObjecCommand;
            offCommands[i]=nullObjecCommand;
        }
    }
    public void configureCommand(int position, Command on, Command off){
        onCommands[position]=on;
        offCommands[position]=off;
    }
    public void executeOnCommand(int position){
        onCommands[position].execute();
    }
    public void executeOffCommand(int position){
        offCommands[position].execute();
    }
    protected class NullObjectCommand implements Command{
        @Override
        public void execute() {
            // NULL-OBJECT-PATTERN
        }
    }
}

Конкретные команды и действия

Здесь мы можем увидеть конкретную реализацию действий и команд.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Door {
    public void on(){
        System.out.println("Opening car doors...");
    }
    public void off(){
        System.out.println("Closing car doors...");
    }
}
public class OpenDoorCommand implements Command {
 
    private Door door;
    public OpenDoorCommand(Door door) {
        this.door = door;
    }
    @Override
    public void execute() {
        door.on();
    }
}
public class CloseDoorCommand implements Command {
 
    private Door door;
    public CloseDoorCommand(Door door) {
        this.door =door;
    }
    @Override
    public void execute() {
        door.off();
    }
}

Универсальный MicroShip

Как вы можете видеть здесь, эта реализация или этот MicroShip может содержать столько команд, сколько вам нужно, и может использоваться повторно в любой ситуации, в которой вы можете нуждаться. В этом MicroShip ниже я реализовал больше, чем только OpenDoorCommand и CloseDoorCommand, так что вы можете увидеть всю мощь этого. Это зависит от вас, чтобы реализовать другие команды, как я сделал. Самое классное здесь, это возможность делать и отменять вещи. Чтобы создать столько команд и выполнить столько действий, сколько нам нужно. Простота и красота этой картины очаровывает меня.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class CarKey {
    private MicroChip microChip;
    public CarKey() {
        final int commandQuantity = 5;
        microChip = new MicroChip(commandQuantity);
         
        final Hood hood = new Hood();
        final OpenHoodCommand openHoodCmd = new OpenHoodCommand(hood);
        final CloseHoodCommand closeHoodCmd = new CloseHoodCommand(hood);
        microChip.configureCommand(0, openHoodCmd, closeHoodCmd);
         
        final Door door = new Door();
        final OpenDoorCommand openDoorCmd = new OpenDoorCommand(door);
        final CloseDoorCommand closeDoorCmd = new CloseDoorCommand(door);
        microChip.configureCommand(1, openDoorCmd, closeDoorCmd);
         
        final Garage garage = new Garage();
        final OpenGarageCommand openGarageCmd = new OpenGarageCommand(garage);
        final CloseGarageCommand closeGarageCmd = new CloseGarageCommand(garage);
        microChip.configureCommand(2, openGarageCmd, closeGarageCmd);
         
        final Trunk trunk = new Trunk();
        final OpenTrunkCommand openTrunkCmd = new OpenTrunkCommand(trunk);
        final CloseTrunkCommand closeTrunkCmd = new CloseTrunkCommand(trunk);
        microChip.configureCommand(3, openTrunkCmd, closeTrunkCmd);
         
        final Alarm alarm = new Alarm();
        final EnableAlarmCommand enableAlarmCmd = new EnableAlarmCommand(alarm);
        final DisableAlarmCommand disableAlarmCmd = new DisableAlarmCommand(alarm);
        microChip.configureCommand(4, enableAlarmCmd, disableAlarmCmd);
    }
     
    public void openHood(){microChip.executeOnCommand(0);}
    public void closeHood(){microChip.executeOffCommand(0);}
    public void openDoor(){microChip.executeOnCommand(1);}
    public void closeDoor(){microChip.executeOffCommand(1);}
    public void openGarage(){microChip.executeOnCommand(2);}
    public void closeGarage(){microChip.executeOffCommand(2);}
    public void openTrunk(){microChip.executeOnCommand(3);}
    public void closeTrunk(){microChip.executeOffCommand(3);}
    public void enableAlarm(){microChip.executeOnCommand(4);}
    public void disableAlarm(){microChip.executeOffCommand(4);}
 
}

FerrariClient

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
public class FerrariClient {
    public static void main(String[] args) {
        final CarKey ferrariSwitchbladeKey = new CarKey();
        ferrariSwitchbladeKey.openHood();
        ferrariSwitchbladeKey.openGarage();
        ferrariSwitchbladeKey.openTrunk();
        ferrariSwitchbladeKey.openDoor();
        ferrariSwitchbladeKey.enableAlarm();
        System.out.println("-------------------------------");
        ferrariSwitchbladeKey.closeHood();
        ferrariSwitchbladeKey.closeGarage();
        ferrariSwitchbladeKey.closeTrunk();
        ferrariSwitchbladeKey.closeDoor();
        ferrariSwitchbladeKey.disableAlarm();
    }
}

Это все. Надеюсь, вам понравится!