Design Pattern: Command Processor

 

Intention

System Management

Systems need to handle collections of objects

For example, events from other systems that need to be interpreted and scheduled

"Define" a manager component to handle incoming homogeneous collections of objects

 

Introduction

"Command Processor" separates the request for a service from its execution

Manages requests as separate objects

Schedule their execution and

Provides additional services such as the storing of request objects for later undo

 

Example

Implement a text editor

Need to provide multi-level undo mechanism

Allows future enhancements

Have callback procedures to automatically called for every human-computer interaction

Implement a CAD editor, Online job scheduler

 

Context

Applications that need flexible and extensible user interfaces, or applications that provide services related to the execution of user functions, such as scheduling or undo

 

Problem

Application needs a large set of fectures

Need a solution that is well-structured for mapping its interface to its internal functionality

Need to implement pop-up menus, keyboard shortcuts, or external control of application via a scripting language

Forces (requirements) are:

Provide different ways for different users to work with an application

Enhancements of the application should not break existing code

Services such as undo should be implemented consistently for all requests

 

Solution

Use the Command Processor pattern

Encapsulate requests into objects

When user call a function, the request is turned into a command object

Command processor component takes care of all command objects

It schedule the execution, provides undo services and other additional services

 

Structure

Abstract command component defines the interface of all command objects

A minimum of the interface is to provide a procedure to execute a command

Additional services require further interface procedure for all command objects

Each user function we derive a command component form the abstract command

Class
  • Abstract Command

Responsibility

  • Defines a uniform interface to execute commands
  • Extends the interface for services of the command processor, such as undo and logging

Collaborators

  • -

 

Class
  • Command

Responsibility

  • Encapsulates a function request
  • Implements interface of abstract command
  • Uses suppliers to perform a request

Collaborators

  • Supplier

Controller represents the interface of the application, it accepts request such as "paste text" and creates the corresponding command objects

Command objects then go to Command Processor for processing

In essense, Controller is like a server waiting for request to map to Command objects

Command Processor manages command objects, schedule them and starts their execution, it is independent of specific commands because it only uses the abstract command interface

Supplier components provide most of the functionality required to execute concrete commands

When an undo mechanism is required, a supplier usually provides a means to save and restore its interal state

Class
  • Controller

Responsibility

  • Accepts service requests
  • Translates requests into commands
  • Transfers commands to command processor

Collaborators

  • Command Processor
  • Command

 

Class
  • Command Processor

Responsibility

  • Activates command execution
  • Maintains commands objects
  • Provides additional services related to command execution

Collaborators

  • Abstract Command

 

Class
  • Supplier

Responsibility

  • Provides application specific functionality

Collaborators

  • -

 

Command Processor ------performs/stores------ Abstract Command
|                                                    |
Transfer command                                   inherit
|                                                    |
Controller -----------------creates--------------- Command ---- uses ----- Supplier

 

Dynamics

Implement an undo mechanism after Capitalizing some text

The controller accepts the request from the user within its event loop and creates a 'capitalize' command object

The controller transfers the new command object to the command processor for execution and further handling

The command processor activates the execution of the command and stores it for later undo

The capitalize command retrieves the currently-selected text from its supplier, stores the text and its position in the document, and asks the supplier to actually capitalize the selection

After accepting an undo request, the controller transfers his request to the command processor. The command processor invokes the undo procedure of the most recent command

The capitalize command resets the supplier to the previous state, by replacing the saved text in its original position

If no further activity is required or possible of the command, the command processor deletes the command object

 

Implementation

Define the interface of the abstract command, it should hide the details of all specific commands (No change, Normal, No undo)

Design the command components for each type of request that the application supports (Delete command to do delete text, etc)

Increase flexibility by providing macro commands that combine several successive commands. Apply the Whole/Part pattern to implement such a macro command component

Implement the controller component

Implement access to the additional services of the command processor (e.g. add the undo command)

 

Variants

Spread controller functionality. The role of the controller can be distributed over serveral components. One sub-controller for GUI, another for other functions

 

Known Uses

MacApp use the pattern to do undo

EZ use the pattern to do undo

WRKJOBJS use the pattern to do job scheduling

 

Consequences

Advantages

Flexibility in the way requests are activated

Different user interface elements for requesting a function can generate the same kind of command object

Flexibility in the number and functionality of requests

Programming execution-related services

Testability at application level

Concurrency

Disadvantages

Efficiency loss

Potential for an excessive number of command classes

Complexity in acquiring command parameters