Command pattern —Part 1

Learn the basics and terminology of command pattern.

Nitin Verma
6 min readSep 6, 2019
Credits : Image from Dreamstime.com

Prerequisite:

  1. If you’re not not familiar with the term ‘design patterns’ make sure to check out my Introduction to design patterns.
  2. You understand java or any other OOP language
  3. You have a basic idea about inheritance, polymorphism, and interfaces.

In this part I will explain this pattern with the help of an illustrative example, we won’t do any coding. Implementation will be covered in part-2.

Let’s say that you want to build a home automation remote control. It will have some slots( or buttons ) and each slot will control a appliance. You can have various appliances such as gate light, living room light, TV, etc.

One common and bad approach to do this would be to add appliance call logic in RemoteControl class itself like this:

// RemoteControl class codeGateLight gateLight = new GateLight();
// some code
// on click of slot 1 do this:
gateLight.on();
// on click of slot 2 do this:
gateLight.off();
// on click of slot 3 do this:
tv.on();
// on click of slot 4 do this:
tv.off();
// other code

There are several reasons why this approach is bad:

  1. Think of it like you own a company which make this remote. Your company only make the remote control, it doesn’t itself make appliances. so your remote will support different vendors. for example Bajaj smart fan or Havells LED smart bulb or Sony smart TV. These vendors will have various operations that can be applied on their appliance. Like let’s say that when sony tv turns on they want to execute this code snippet in sequence :
    tv.on(); // turn it on
    tv.setVolume(5); // set the volume to mid when it turns on
    tv.setChannel(0); // set the channel to 0 when it turns on
    tv.setBrightness(60); // set the brightness to 60 when it turns on
    Now how do you think you as a engineer in remote control company is going to get this code snippet. Do you think every vendor will mail you code snippets like this on how to actually perform a operation and then you will add that snippet in RemoteControl class? Obviously NO !!
    So what’s currently wrong with our approach is that vendors are exposing their API and we are trying to implement them by calling them. But what should actually happen is that we should expose some API and those vendors who want their appliance to be controlled by our remote should implement our API. so basically we are doing exact opposite! This point is the most important, I hope that it’s clear to you. give it a read 2–3 times or ask me in comment section if you have any doubt.
  2. Not all appliances will only have on and off function. like you have seen in previous point we can have a range of methods like setChannel , setVolume , etc. So we can have diverse vendors and diverse methods of each appliance. If we provide implementation of all buttons then our RemoteControl class will be very hard to maintain and making changes in it will be a nightmare.
  3. This approach doesn’t follow open-close principle, there is no separation of concerns, high coupling, not modular and definitely not scalable.
    ( if you don’t know about these terms, search and learn about them. These are very important and common in design patterns. )

So this is what we are going to do. we will load each button of remote with some object. This object will know how to do the operation. Remote will not have any idea what the work is or who is going to do the work, it just knows that it has a object for each button that knows how to talk to the right appliance to get the work done. This way our remote is decoupled from the actual appliance. This way our remote is dumb and we have delegated all of the responsibility to this object. You will get to know about this mysterious super-intelligent object in part-2. This is the magic of command pattern, It allows you to decouple the requester of action from the object that actually performs the action.

Before moving on to part-2 and coding, first let’s see a real life example which will help you understand this pattern even better.

So you are in a restaurant and you want to eat one burger and a shake. You give your order to waitress. She writes it down on a piece of paper and goes inside and yells “order up” and gives the paper to cook. He prepares your order and you eat it. This Example is insanely simple but we will try to go deep into it and map this procedure with command pattern.

Here are few points to note:

  1. Do you know how to make burger and shake? Does waitress know how to prepare food items? Answer is clearly NO. Only cook knows how to prepare these items. You don’t tell the procedure when you give order, only thing that you have to do is select food items and the job of waitress is to take order from you and give it to cook.
  2. So you don’t know how to make food items but still once you give order, you get that food item magically. maybe it’s not magical for you but wait, compare it with our original problem of home automation remote : what if we do something so that remote button doesn’t know how to turn on TV but once user presses it, magically TV turns on. Read the point again, maybe now you will find it magical 🔥
    So if you or waitress don’t know about the procedure to prepare food item, why should our remote control class know the procedure to turn on the TV or any other appliance?
  3. So all of this magic is happening because of one very important thing which is Order. yes that piece of paper on which order is written is the real Hero here. Think of it like this, every order implements some interface and override one method orderUp(). when waitress receives a order object, she goes inside and yells “order up”(or execute orderUp() method) and passes it to cook.
    some important mapping from this point to command pattern:
    1) we’ll call this order object as Command Object. we will have various commands such as LightOnCommand, TvOnCommand, etc
    2) Each command object implements Command interface which has only one method execute(). You can map OrderUp to this method.
    3) we will call our cook as Receiver. He is the one who knows how to actually do the task. for example in LightOnCommand we will have a object of Light as receiver and in overriden execute method, we’ll do light.on(); ( don’t worry if you don’t get it, you will see this in next part. just remember the mappings. )
    4) Once the execute method is called, the receiver takes over and executes the task just like how cook takes over and prepares the meal.
  4. Just like waitress took the order(call it takeOrder() or setOrder()), we’ll call this procedure as setting a command(or setCommand()).
  5. So this is what we’ll do in part-2 : set some command on a button. when button is pressed call command.execute() and in the overrided execute method, actually do the operation with the help of receiver.

I’m sure you are confused with all of these new terms (and you should be) but don’t worry everything will be clear in part-2. Here’s a recap of mappings and do give this article one more read before moving on.

Order -- Command
takeOrder() -- setCommand()
orderUp() -- execute()
cook -- Receiver

Let’s continue with part-2

Clap 👏 , Comment and share your valuable feedback and don’t forget to ask more questions in comment section below.

Let’s connect on LinkedIn and GitHub.

References:
- Head first design patterns book.

--

--

Nitin Verma

Android developer, GIS, writer, Punjabi who love to share knowledge ✌️