Architecture:MediaWiki/command pattern

From mediawiki.org


The command pattern is used when modelling domain verbs in the behavior layer. Commands typically perform an action on the storage layer, surrounded by additional behavior layer activity such as permission checks and notifications.

Classes implementing the command pattern model system behavior in an application domain. They should not know about user interaction. In particular, they should not know about web requests or response, user interface components, or localization (though they may use internationalization, e.g. for error or status messages).

Command objects typically offer a single method to execute the command. Setters may be used to configure the behavior. Getters may be used to retrieve status information after execution.

Instantiation:
Command objects are obtained from a service object that acts as a factory. Factory functions for several or all commands of a given domain should be grouped together in a single service, which acts as the domain command factory.

Related patterns:

  • The action pattern is conceptually similar to the command pattern, but belongs to the user interface layer. An action is concerned with presenting an user interface and handling user input. It may rely on a command or other classes from the behavior or storage layer to perform the task requested by the user.
  • Similarly, an API module provides the interaction (handing of input and output) for performing a task, and may delegate the task itself to a command. There will often be a UI action and an API module for the the same task. In that case, their shared functionality should be encapsulated in a command, or a service object.
  • It is always possible to use a service object instead of a command class. A command is essentially a part of a service object that was split out for convenience. This is particularly useful for behavior that has a lot of input parameters or produces complex output, which would be awkward to model as a single method call.

NamingConvention:
Classes implementing the command pattern should start with a verb belonging to the domain, typically followed by the object to operate on, optionally followed by he word "Command". E.g. BlockUserCommand, SubscribeCommand, MovePage.

Layer constraint:
The command pattern should be used only in the behavior layer. Similar patterns for use in the user interface layer are the action and the API module.

Status:
As of May 2020, the command pattern has some uses but is not fully established in MediaWiki. In many cases, command logic is inlined in the user interface layer (typically in SpecialPages, Actions, API modules), and may access the database directly without the use of abstractions in the storage layer. When such classes are refactored, we should see more and more commands classes being extracted, to provide separation of concerns along the layers and to allow re-use of code between APIs and the browser based UI.

Examples:
An example of the command pattern is the MovePage class.