Using Command Design pattern
Asked Answered
D

6

20

Can anyone explain with a simple example the Command Pattern? I tried searching on the internet, but I got confused.

Denticulate answered 6/1, 2010 at 19:23 Comment(2)
en.wikipedia.org/wiki/Command_patternOrmsby
medium.com/swlh/… I found this usefulPenick
S
23
public interface Command {
   public void execute();
}

For the most part, commands are immutable and contain instructions that encapsulate a single action that is executed on demand. You might also have a RuntimeCommand that accepts instructions upon execution, but this delves more into the Strategy or Decorator Patterns depending on the implementations.

In my own opinion, I think it's very important to heed the immutable context of a command otherwise the command becomes a suggestion. For instance:

public final class StopServerCommand implements Command {
    private final Server server;

    public StopServerCommand(Server server) { this.server = server; }

    public void execute() {
        if(server.isRunning()) server.stop();
    }
}

public class Application {
    //...
    public void someMethod() {
        stopButton.addActionListener(new ActionListener() {
            public void actionPerformed(Event e) {
                 stopCommand.execute();
            }
        });
    }
}

I personally don't really like commands. In my own experience, they only work well for framework callbacks.

If it helps, think of a command in a metaphorical sense; a trained soldier is given a command by his/her commanding officer, and on demand the soldier executes this command.

Synergistic answered 6/1, 2010 at 20:27 Comment(4)
@Droo, follow-up to your "don't really like" - they're actually a very natural implementation for things like abstracting device control. For example, I used to have to drive a variety of cameras (that all use different serial protocols) using a common joystick. It was very helpful to have a Command for "Pan", another for "Zoom", etc.Orsa
@Droo: can you explain with simple example?Denticulate
@Synergistic where the hell did the object stopCommand get created?Glick
Agree with @RomanticElectron comment. This is where the power of command comes in. stopCommand (and so may others) could be created and injected by an IOC framework (e.g. Spring) who decouples the action from the caller.Propriety
C
15

You can think of Command pattern workflow as follows.

Client calls Invoker => Invoker calls ConcreteCommand => ConcreteCommand calls Receiver method, which implements abstract Command method.

Code snippet:

interface Command {
    void execute();
}
interface Receiver {
    public  void switchOn();
       
}
class OnCommand implements Command{
    private Receiver receiver;

    public OnCommand(Receiver receiver){
        this.receiver = receiver;
    }
    public void execute(){
        receiver.switchOn();
    }
}
class Invoker {
    private Command command;

    public Invoker(Command command){
        this.command = command;
    }
    public void execute(){
        this.command.execute();
    }
}

class TV implements Receiver{

     public void switchOn(){
        System.out.println("Switch on from TV");
    }
}
class DVDPlayer implements Receiver{

    public void switchOn(){
         System.out.println("Switch on from DVDPlayer");
    }
}

public class CommandDemoEx{
    public static void main(String args[]){
        // On command for TV with same invoker 
        Receiver receiver = new TV();
        Command onCommand = new OnCommand(receiver);
        Invoker invoker = new Invoker(onCommand);
        invoker.execute();

        // On command for DVDPlayer with same invoker 
        receiver = new DVDPlayer();
        onCommand = new OnCommand(receiver);
        invoker = new Invoker(onCommand);
        invoker.execute();            
    }
}

output:

Switch on from TV
Switch on from DVDPlayer

Explanation:

In this example,

  1. Command interface defines execute() method.
  2. OnCommand is ConcreteCommand, which implements execute() method.
  3. Receiver is an interface and implementers have to provide implementation for the methods.
  4. TV and DVDPlayer are two types of Receivers, which are passed to ConcreteCommand like OnCommand.
  5. Invoker contains Command. It's the key to de-couple Sender from Receiver.
  6. Invoker receives OnCommand -> which calls Receiver (TV) to execute this command.

By using Invoker, you can switch on TV and DVDPlayer. If you extend this program, you switch off both TV and DVDPlayer too.

You can use Command pattern to

  1. Decouple the sender & receiver of command

  2. Implement callback mechanism

Charlottcharlotta answered 14/1, 2016 at 12:45 Comment(3)
The Key features: you wrote here is super helpful at least for me, do you have/know any blog or something so I can find such an explanation for other design patterns? I mean like you did hereGogetter
You can find my other posts on design patterns with above format.Charlottcharlotta
This was very helpful indeed. I was wondering though, would you ever wire up your Command to DI? And then inject it at the invoker? I found my Command objects requiring 4-6 dependencies to construct the command and send it to the receiver. I ended up manually newing up the command object and using scoped service provider to get references to all dependencies of the Command object and then passing them into the Commands ctor. It feels weird so wanted to ask for opinionsBaxy
A
8

Here is another example you can use to understand how command pattern works, using real life scenarios: You cannot travel from one place to another by airplane without using the command pattern!

If you are a frequent traveler, all you care about as a client is to travel from where you are to another . you don't care about how the pilot will fly the plane or which airline will be available .. you cant really predict that. all you want is to get the the air port and tell them to take you to your destination.

But if you do that, your command to the airport authorities will be laughed at! they need you to supply a command object, which is your ticket. as much as you don't care about which airline or which plane type, when you are ready to fly, you need to supply a ticket command object. The invoker, which is the airport officials needs to check your command (ticket) so that they can validate it, undo it if it is fake, redo it if they made a mistake (without you having to go through the booking process all over).

In short , they want to have complete control of your command (ticket) before deciding whether or not to invoke or execute your command, which lets the airline (the receiver ) execute ( put you on a plane and take you to your destination) .

Mind you, your command (your ticket) already has the information of the receiver (airline) without which the airport officials wont even start to process your ticket in the first place.

The airport authorities could even have a bunch of tickets they are working on. they may choose to delay my ticket and let someone that came after me go through (invoke another persons ticket before mine)

Here is the code :

 [TestClass]
    public class Client
    {
        [TestMethod]
        public void MyFlight_UsingCommandPattern()
        {
            var canadianAirline = new Airline();

            AirlineTicket_Command myTicket = new MyAirLineTicket(canadianAirline);

            var airportOfficials = new AirportOfficials_Invoker(myTicket);
            airportOfficials.ProcessPasengerTicket_And_AllowPassengerToFly_Execute();

            //assert not implemented
        }
    }

    public class AirportOfficials_Invoker
    {
        private AirlineTicket_Command PassengerTicket { set; get; }

        public AirportOfficials_Invoker(AirlineTicket_Command passengerTicket)
        {
            throw new NotImplementedException();
        }

        public void ProcessPasengerTicket_And_AllowPassengerToFly_Execute()
        {
            PassengerTicket.Execute();
        }
    }

    public abstract class AirlineTicket_Command
    {
        protected Airline Airline { set; get; }

        protected AirlineTicket_Command(Airline airline)
        {
            Airline = airline;
        }

        public abstract void Execute();
    }

    public class MyAirLineTicket : AirlineTicket_Command
    {
        public MyAirLineTicket(Airline airline)
            : base(airline)
        {
        }

        public override void Execute()
        {
            Airline.FlyPassenger_Action();
        }
    }

    public class Airline
    {
        public void FlyPassenger_Action()
        {
//this will contain all those stuffs of getting on the plane and flying you to your destination
        }
    }
Alonsoalonzo answered 27/2, 2014 at 5:29 Comment(0)
P
3

My requirement is to perform a sequence of tasks (which can be re-used in several Usecases) each with its own exception flow. Found Command pattern's implementation logical here.

I am trying to make it like each action executed by the command (whether normal/alternate flow) can be an exception handler too. However, If the command is registered with another handler then this should be used. Any suggestions for improvement/correction are welcome.

public interface Command {
    Result run() throws Exception;
    Command onException(ExceptionHandler handler);
}

public class Result {
}

public interface ExceptionHandler {
    void handleException(Exception e);
}

public interface Action {
    Result execute() throws Exception;
}

public class BasicCommand implements Command {
private Action action;
private ExceptionHandler handler;

public BasicCommand(Action action) {
    if (action == null) {
        throw new IllegalArgumentException("Action must not be null.");
    }
    this.action = action;
    this.handler = (ExceptionHandler) this.action;
}

@Override
public Command onException(ExceptionHandler handler) {
    if (handler != null) {
        this.handler = handler;
    }
    return this;
}

public Result run() throws Exception {
    Result result = null;
    try {
        result = action.execute();
    } catch (Exception e) {
        handler.handleException(e);
    }
    return result;
}

}

public class BasicAction implements Action, ExceptionHandler {
    private Object[] params;


    public BasicAction(Object... params) {
        this.params = params;
    }

    @Override
    public Result execute() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void handleException(Exception e) {
        // TODO exception translation: prepare unchecked application. exception and throw..
    }
}

public class Main {

    public static void main(String[] args) throws Exception {
        int param1 = 10;
        String param2 = "hello";

        // command will use the action itself as an exception handler
        Result result = new BasicCommand(new BasicAction(param1, param2)).run();

        ExceptionHandler myHandler = new ExceptionHandler(){
            @Override
            public void handleException(Exception e) {
                System.out.println("handled by external handler");
            }
        };
        // command with an exception handler passed from outside.
          Result result2 = new BasicCommand(new BasicAction(param1, param2)).onException(myHandler).run();

    }
}
Propriety answered 30/3, 2012 at 14:0 Comment(0)
L
1

Command Design Patterns decouples invoker of service and provider of service. In general scenario, say for eg., If Object A wants service of Object B, it'll directly invoke B.requiredService(). Thus, A is aware about B. In Command pattern, this coupling is removed. Here, there's an intermediate object known as Command, which comes into picture. Thus, A deals with Command object and command object deals with actual object B. This approach has several applications such as designing applications, which are :-

  • Accepts commands as requests.
  • Undoing requests.
  • Requests requests.
  • Creating macros.
  • Creating Task Executors and Task Managers.

For more information regarding, Command Design Pattern, I'll recommend https://en.wikipedia.org/wiki/Command_pattern. For all other design patterns, refer to https://www.u-cursos.cl/usuario/.../mi_blog/r/head_first_design_patterns.pdf

Lantz answered 10/11, 2016 at 4:54 Comment(0)
D
1

I would try to give you another rough analogy here.

Suppose that one day God calls on you and tells you that the world's in danger and He needs your help to save it. Further helping you , He tells you that He has sent some superheroes on earth.

Since He doesn't know oops and hence He doesn't call them superheroes (doesn't provide you any interface or abstract class over them) but just tell you their names for ex - batman, superman, iron man and the powers they have.

He also says that in future He might send more such guys in future.

Now He assigns you special responsibility -> control them and for that provides you with seven hands. He doesn't fixes the task of each hand Himself but leaves it on you.

You want flexibility in assigning any hand control of any superhero's power and don't want to repeatedly change things through multiple conditions.

You are in a fix. What do you do now?

Enter Command Pattern.

Create an interface Command and has only one method execute() in it. Encapsulate every power of each superhero and make that implement Command for ex - IronManCreatesSuitCommand

Now you can assign any hand to any command at any time giving you lot more flexibility because now none of your hands cares about the specific task it has to do. You just assign it any command to it. It calls execute on it and the command takes care of everything else.

Now even when God sends any other superhero with different powers, you know what to do.

Dactylic answered 18/8, 2019 at 13:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.