Command

Command design pattern is to encapsulate a request as an object, allowing one to parameterize clients with different requests, queue or log requests, and support undoable operations. The keyword is to wrap the command into an object for later executions. Here is the diagram:

When To Use (Problem)

  • The problem where one needs to issue request without knowing anything about the operations.
  • The problem where one needs to sequences up the executions commands and perform "forward doing" (redo) and "reverse doing" (undo).
  • The problem requires one to facilitates flexible command execution at a given time.

Example (Solution)

Here is an example using Go:

package main

import (
        "fmt"
)

// list of commands
type Chef1 struct {
}

func (c *Chef1) Execute() {
        fmt.Printf("I cook seafood!\n")
}

type Chef2 struct {
}

func (c *Chef2) Execute() {
        fmt.Printf("I prepare side dishes\n")
}

// commander
type Desk struct {
}

func (d *Desk) CheckIn(orders []string) {
        for _, o := range orders {
                switch o {
                case "seafood":
                        fallthrough
                case "blackpepper-lobsters":
                        fallthrough
                case "fish-and-chips":
                        chef1 := Chef1{}
                        chef1.Execute()
                case "ceaser-salad":
                        fallthrough
                case "cawamushi":
                        chef2 := Chef2{}
                        chef2.Execute()
                }
        }
}

// director
type Waiter struct {
}

func (w *Waiter) PlaceOrder(orders ...string) {
        d := Desk{}
        d.CheckIn(orders)
}

// restaurant
func main() {
        w := Waiter{}
        w.PlaceOrder("seafood",
                "carbonara",
                "cawamushi",
                "fish-and-chips",
        )
}

// Output:
// I cook seafood!         // item: seafood
// I prepare side dishes   // item: cawamushi
// I cook seafood!         // item: fish-and-chips

There are 3 layers of encapsulations here using the command pattern:

  1. The restaurant which is the client, placing order from the waiter
  2. The waiter, acts as a director, place the order at the Command desk
  3. The Command desk commands the corresponding receivers Chef to cook corresponding dishes

Note that:

  • The waiter does not know the menu.
  • The client is assumed knowing the keyword for the particular dish (the command keyword)
  • The commanding desk acts as a coordinator (or commander) to perform corresponding dishes.

Expected Outcome (Consequences)

  • Back-end receiver implementations are isolated from front-end.
  • Central coordinator helps coordinate/direct commands flow from front-end to back-end and vice versa.