Published on

Learning Design Patterns: Command Pattern - Your Job Is To Command

Authors

The Command Pattern is a Behavioral Pattern with the idea of encapsulating requests in your software program within an Object (this object contains all the necessary information to execute) and processing them when needed. Whenever something needs to be done, you simply send an Object containing the details, and the recipient will execute it according to the requirements and specifications you have defined.

Common patterns: TaskExecutors (Java), Handler (Android Threads), Flow (Kotlin Coroutines), RxJava, Event Queue, ...

Problem in Software: UI and Logic

Imagine a familiar situation in Mobile app development: building a UI with Buttons and Menus to trigger various operations.

A simple approach is to directly code the UI Event handling at the moment the Event is received to ensure the immediacy of those Events.

However, this approach can lead to some issues:

  • UI and Logic are intertwined: UI code depends directly on Biz Logic, making it difficult to modify or reuse components independently.
  • Code is likely to be duplicated: The same logic may need to be triggered from multiple UI Elements, resulting in repeated code.

Solution: Commander Appears

The Command Pattern offers a solution by using a Mid-man: a Command Object. Instead of a UI directly executing an action/function, it creates a Command Object. This Object encapsulates all the necessary information about that action:

  • Who is the Receiver?
  • What is the Action?
  • What are the Params (parameters) values?

The UI (acting as the Sender or Invoker) simply triggers the Command with the Command Object, which then takes care of executing the action on the appropriate Receiver.

This creates a clear separation between UI and Business Logic.

Benefits of the Command Pattern

  • Parameterizing Function Calls: Your function calls can now be easily parameterized into an Object and separated from the caller. This helps us break down the code to a significant extent, which is effective because the more the code is broken down, the easier it is to Test and write Unit Tests.
  • Full Delay, Suspend, Defer, or Drop control: Commands created can be put into a Queue and executed at a later time. We can use this flexibility to solve problems related to asynchronicity and deadlocks through sequential mechanisms.
  • Logging: When all Commands are placed in a Queue, it means you have full control and oversight of the Commands. At this point, we can deploy a logging system to control the system's status, serving as a trace back later when needed.

Follow my Youtube and Facebook channels to update more knowledge!