Continuando con el repaso a los patrones del diseño del software, llegamos al Command o Comando. También es llamado el patrón Action o Transaction. Permite encapsular acciones en objetos programados, de forma que facilita el mantenimiento y ampliación de la aplicación que tengamos entre manos.
Esto facilita el uso de colas, la ejecución en background, mantenimiento de estados, tener históricos, poder revertir cambios, etc.. desacoplando interfaces, puertos, clientes, controladores, etc.. del resto de la aplicación, haciendo independiente la forma de ejecución de todas estas acciones de la forma en que se lancen.
Es decir, si independizamos las acciones en comandos, nos dará igual si luego se llaman desde interfaces gráficas, una o varias, desde línea de comandos, peticiones en una API RESTful, etcétera.
Líneas generales para la implementación
Simplificando la teoría, podemos tener una interfaz que defina el contrato de Comando, para luego tener tantos comandos como queramos. Esto a su vez se puede escalar usando otros patrones de diseño, pero lo más simple podría quedar por ejemplo así:
Lo único obligatorio en este caso es que todos los comandos tengan un método de ejecución, pero se podrían definir así también:
Al grano, un caso de ejemplo en PHP
Hay varias formas de implementar estos comandos, acciones o transacciones, una posible podría ser:
<?php
interface ICommand
{
public function execute();
}
Arriba tenemos una definición de contrato de uso que simplemente obliga a tener una función de ejecución. A continuación tres implementaciones posibles que encapsulen todo lo necesario para ejecutarse dentro del comando:
<?php
class SomethingToProcess1Command implements ICommand
{
private $_config;
public function execute()
{
/*
* Do something fully encapsulated into the class..
*/
}
public function setConfig($_config)
{
$this->_config = $config;
}
}
<?php
class SomethingToProcess2Command implements ICommand
{
private $_state;
public function execute()
{
/*
* Do something fully encapsulated into the class..
*/
}
}
<?php
class SomethingToProcess3Command implements ICommand
{
private $_entity;
public function __construct($entity)
{
$this->_entity = $entity;
}
public function execute()
{
/*
* Do something fully encapsulated into the class..
*/
}
}
La forma más sencilla sería el comando 2 que desde un cliente podría llamarse así:
$command = new SomethingToProcess2Command();
$command->execute();