Command design Pattern in Kotlin

Command design pattern is used to encapsulate a request as an object and pass to an invoker, wherein the invoker does not knows how to service the request but uses the encapsulated command to perform an action.

To understand command design pattern we should understand the associated key terms like client, command, command implementation, invoker, receiver.

  • Command is an interface with execute method. It is the core of contract.
  • A client creates an instance of a command implementation and associates it with a receiver.
  • An invoker instructs the command to perform an action.
  • A Command implementation’s instance creates a binding between the receiver and an action.
  • Receiver is the object that knows the actual steps to perform the action.

When to use the Command Pattern

  • When the requests need to be handled in certain time occurrences and according to different triggers situations
  • When the client and the service provider needs to be decoupled
  • When there is a need for rollback functionality for certain operations
  • When the history of requests required
  • When there is a need to add new commands
  • When there is a need for parameterizing objects according to an action

Real life Example for Command Pattern

It will be easier to understand command pattern with an example. Let us think of developing a universal remote. Our UniversalRemote will have only two buttons, one is to power on and another is to mute all associated ConsumerElectronics.

For ConsumerElectronics, we will have couple of implementations Television and SoundSystem. Button is a class that is the invoker of an action.

OnCommand is used to switch on a ConsumerElectronics. While instantaiting OnCommand client needs to set the receiver. Here receiver is either Television or SoundSystem.

UniversalRemote class will maintain all the receivers and will provide a method to identify the currently active receiver.

When an instance of a invoker is created, a concrete command is passed to it. Invoker does not know how to perform an action. All it does is honoring the agreement with the Command. Invoker calls the execute() method of the set concrete command.

Complete program for Command design pattern in kotlin

import kotlin.collections.ArrayList

interface Command {

    fun execute()
}

class OnCommand(private val ce: ConsumerElectronics) : Command {

    override fun execute() {
        ce.on()
    }
}

class MuteAllCommand(internal var ceList: List<ConsumerElectronics>) : Command {

    override fun execute() {

        for (ce in ceList) {
            ce.mute()
        }
    }
}

interface ConsumerElectronics {
    fun on()
    fun mute()
}

class Television : ConsumerElectronics {

    override fun on() {
        println("Television is on!")
    }

    override fun mute() {
        println("Television is muted!")
    }
}

class SoundSystem : ConsumerElectronics {

    override fun on() {
        println("Sound system is on!")
    }
    override fun mute() {
        println("Sound system is muted!")
    }
}

class Button(var c: Command) {

    fun click() {
        c.execute()
    }
}

class UniversalRemote {

    // here we will have a complex electronic circuit :-)
    // that will maintain current device
    fun getActiveDevice() : ConsumerElectronics{
        val tv = Television()
        return tv
    }
}

fun main(args: Array<String>) {

    // OnCommand is instantiated based on active device supplied by Remote
    val ce = UniversalRemote.getActiveDevice()
    val onCommand = OnCommand(ce)
    val onButton = Button(onCommand)
    onButton.click()

    val tv = Television()
    val ss = SoundSystem()
    val all = ArrayList<ConsumerElectronics>()
    all.add(tv)
    all.add(ss)
    val muteAll = MuteAllCommand(all)
    val muteAllButton = Button(muteAll)
    muteAllButton.click()
}			

Output of the kotlin Command Pattern


Television is on!
Television is muted!
Sound system is muted!

Important Points on Command Pattern

  • Command pattern helps to decouple the invoker and the receiver. Receiver is the one which knows how to perform an action.
  • Command helps to implement call back in java.
  • Helps in terms of extensibility as we can add new command without changing existing code.
  • Command defines the binding between receiver and action.
  • A command should be able to implement undo and redo operations. That is restting the state of the receiver. It can be done from the support of receiver.

 
Join My Facebook Group
Join Group
 
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions