Command Design Pattern Applied

Hi there!

Today i’m gonna share with you a really great programming design pattern. It has a lot of usages and it is one of my favorites. The programming degin pattern command has a huge variety of use cases. In this post we will see how to implement something from the real world.

We will implement an electronic car key to open, close doors, enable, disable alarms, open, close the garage door or to open and close the hood and trunk of your car.

The example i will show to you, is a very generic one, so you can always come back here, take it and use it in your applications.

The UML Command Pattern

As you know me, i always start my projects by showing the class diagram over a UML diagram. This help us to fix it overview the example in a nice, compact way.

command_action

Explaning the Details Programming Design

Our client is the Ferrari Owner (FerrariCleint). It has a CarKey. The CarKey has a generic MicroShip (Involker) that can be configurated with commands. The commands (OpenDoorCommand) itself have Action (DoorAction) to execute. The CarKey can configurate do and undo Commands. The NullObjectCommand belongs to the Null Object Design Pattern and it will be also used here. Let’s see in the code the implementation details now.

Command and MicroShip

The NullObjectCommand is used here to avoid null pointer exceptions and to execute nothing as long as no command has been defined.

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
        }
    }
}

Concrete Commands and Actions

Here we can see the concrete implementation of Actions and Commands.

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

The Generic MicroShip

As you can see here, this implementation or this MicroShip can hold as many commands as you need and can be reused in any situation you may need. In this MicroShip bellow i have implemented more then only this OpenDoorCommand and CloseDoorCommand above, so you can see the power of it. It is up to you to implement other commands like i did.The cool thing here is the ability to do and undo things. To create as many commands and exucute as many actions as we need. The simplicity and beauty of this pattern fascinates me.

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

}

The FerrariClient

Finally we can see the usage and power of this beautiful design pattern. In this example i implemented more than one command to show to you, how it could looks like.

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

That’s all. Hope you like it!

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

2 Responses to "Command Design Pattern Applied"

  1. nice, i like it, just a qualification. I think it should be better to use some kind of enum type in order to execute something like this:

    microChip.executeOnCommand(0);

    instead of to use 0, i think its more clear to use an enum.

    Thank you very much.

Leave a Reply


× nine = 36



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close