Está en la página 1de 8

Ingeniería del Software II

Unicomfacauca

COMMAND (COMANDO, MANDATO)

Resumen
Utilizando el patrón command, el invocador, que emite una solicitud en representación de un cliente, y
el conjunto de servicios de los objetos receptores, pueden ser desacoplados. El patrón sugiere crear
una abstracción para el procesamiento o acción a ejecutar, en respuesta a la solicitud del cliente.

Descripción
En general una aplicación orientada a objetos consiste en la interacción de objetos que ofrecen una
funcionalidad. En respuesta a la interacción del usuario, la aplicación ejecuta algún tipo de
procesamiento. Para este propósito la aplicación utiliza servicios de diferentes objetos para los
requisitos de procesamiento. En términos de implementación, la aplicación puede depender de un
objeto designado que invoca los métodos de esos objetos mediante el paso de argumentos (Ver Figura
1). A este objeto se lo denomina invoker, y se encarga de invocar las operaciones de los diferentes
objetos. El invocador puede ser tratado como parte de la aplicación cliente. Los objetos que ofrecen los
servicios para procesar solicitudes se denominan objetos receiver (receptores).

Figura 1: Interacción de objetos: antes de aplicar el patrón Command

En este diseño el objeto invocador podría tener muchas instrucciones if:


if (RequestType=TypeA){
//do something
}
if (RequestType=TypeB){
//do something
}

Cuando un nuevo tipo de característica se adicione a la aplicación, el código existente debe ser
modificado y de esta forma se violaría el principio open-closed.
...
if (RequestType=NewType){
//do something
}

Utilizando el patrón command, el invocador, que emite una solicitud en representación de un cliente, y
el conjunto de servicios de los objetos receptores, pueden ser desacoplados. El patrón sugiere crear
1
Ingeniería del Software II
Unicomfacauca
una abstracción para el procesamiento o acción a ejecutar, en respuesta a la solicitud del cliente.

Esta abstracción puede ser diseñada como una interfaz común a ser implementada por diferentes
implementadores concretos, denominados como Objetos de comando (Command objets). Cada objeto
command representa un tipo diferente de solicitud cliente y el correspondiente procesamiento. En la
Figura 2, la interface Command representa la abstracción. Su método execute, es implementado por dos
clases implementadoras (ConcreteCommand_1 y ConcrteCommand_2).

Figura 2: Jerarquía de objetos command

Un objeto Command es responsable de ofrecer una funcionalidad requerida para procesar la solicitud
que representa, pero no contiene la implementación de la funcionalidad. Los objetos command hacen
uso de los objetos Receiver para ofrecer sus funcionalidades (Ver Figura 3).

Figura 3: Diseño después de aplicar el patrón command


A continuación se muestra la interacción que ocurre cuando la aplicación cliente necesita un servicio:

2
Ingeniería del Software II
Unicomfacauca
1. Se crean los objetos Receiver necesarios.
2. Se crea el objeto Command apropiado y se configura con sus objetos receiver del paso 1.
3. Se crea una instancia del invocador y se configura con su objeto Command del paso 2.
4. El invocador ejecuta el método execute() sobre el objeto Command.
5. Como parte de su implementación el método execute, un típico objeto Command, invoca los
métodos necesarios sobre los objetos Receiver.
En este nuevo diseño se debe aclarar:
• El cliente/invoker no interactúa direcatamente con los objetos Receiver, logrando el
desacople entre el uno y el otro.
• Cuando la aplicación necesita ofrecer una nueva característica, un nuevo objeto Command
puede ser adicionado. Esto no requiere hacer cambios en el código del invoker. Por lo tanto,
se cumple con el principio open-closed.
• Debido a que la solicitud es diseñada en forma de un objeto, se abre un conjunto de
posibilidades como:
• Almacenar un objeto Command como mecanismo de persistencia para ser
ejecutado posteriormente, y además, aplicar procesamiento inverso y lograr la operación
deshacer.
• Agrupar varios objetos Command para ser ejecutados como una unidad
(Transacción).

Ejemplo
Construiremos una aplicación que gestione items (artículos) de una librería. Los items de una librería
incluyen: libros, videos y DVDs. Estos items son agrupados en categorías. Un item puede pertenecer a
una o varias categorías (Ver Figura 4).

Figura 4: Asociación Item-Category


Las clases Item y Category represenan los items y las categorías de la librería. Aplicando el patrón
Command, las acciones que procesan las solicitudes de adicionar un item y borrar un item se diseñan
como implementadores de una interfaz CommandIterface. La interfaz CommandInterface tiene una
abstracción para procesar la respuesta cuando se agrega y se elimina un item. Las clases
implementadoras AddCommand y DeleteCommand representan las solicitudes para agregar y borrar un
item (Ver Figura 5).

3
Ingeniería del Software II
Unicomfacauca

Figura 5: Jerarquía de objetos Command

La clase ItemManager es la clase invocadora. ItemManager contiene un objeto Command. Invoca el


método execute como parte de su proceso de implementación. Finalmente, provee un método
setCommand para permitir a los objetos cliente configurar el objeto Command.

public class ItemManager {


CommandInterface command;

public void setCommand(CommandInterface c) {


command = c;
}

public void process() {


command.execute();
}
}

Para adicionar o borrar un item, un cliente (CommandTest) sigue los siguientes pasos:
1. Crea los objetos Item y Category necesarios. Estos objetos son los receivers (recibidores).
2. Crea un objeto Command apropiado que corresponde a la actual solicitud. El conjunto de
objetos Receiver del paso 1 son pasados al objeto Command en el momento de su creación.
3. Crea una instancia de ItemManager y se configura con el objeto Command creado en el paso 2.
4. Se invoca el método process() de ItemManager. En seguida, ItemManager invoca el método
execute sobre el objeto command. El objeto command a su vez, invoca los métodos del objeto
receiver necesarios. Diferentes objetos Item y Category procesan la solicitud actual. Por
simplicidad no hay lógica de acceso a bases de datos, en su lugar, se visualizan únicamente
mensajes.
Cuando el programa se ejecuta, se obtiene la siguiente salida:
Item 'A Beautiful Mind' has been added to the 'CD' Category
Item 'Duet' has been added to the 'CD' Category
Item 'Duet' has been added to the 'New Releases' Category
Item 'Duet' has been deleted from the 'New Releases' Category

A continuación, se muestra el diagrama de clases completo:

4
Ingeniería del Software II
Unicomfacauca

Figura 6: Diagrama completo

El siguiente diagrama muestra el flujo de mensajes cuando se agrega y elimina un item a una categoría.

Figura 7: Flujo de mensajes

5
Ingeniería del Software II
Unicomfacauca

Código fuente en Java


A continuación el código fuente en java.
import java.util.HashMap;
/**
* Representa un item de una libreria
*
*/
public class Item {
private HashMap categories;
private String desc;

public Item(String s) {
desc = s;
categories = new HashMap();
}

public String getDesc() {


return desc;
}

public void add(Category cat) {


categories.put(cat.getDesc(), cat);
}

public void delete(Category cat) {


categories.remove(cat.getDesc());
}
}

import java.util.HashMap;
/**
* Representa un categoria de la libreria
*
*/
public class Category {
private HashMap items;
private String desc;

public Category(String s) {
desc = s;
items = new HashMap();
}

public String getDesc() {


return desc;
}

public void add(Item i) {


items.put(i.getDesc(), i);
System.out.println("Item '" + i.getDesc() + "' has been added to the '"
+ getDesc() + "' Category ");
}

6
Ingeniería del Software II
Unicomfacauca
public void delete(Item i) {
items.remove(i.getDesc());
System.out.println("Item '" + i.getDesc()
+ "' has been deleted from the '" + getDesc() + "' Category
");
}
}

public interface CommandInterface {


public void execute();
}

/**
* Solicutud para agregar un item a una categoria
*
*/
public class AddCommand implements CommandInterface {
private Item item;
private Category category;
public AddCommand(Item item, Category category){
this.item = item;
this.category = category;
}
public void execute() {
item.add(category);
category.add(item);
}
}
/**
* Solicitud para borrar un item de una categoria
*
*/
public class DeleteCommand implements CommandInterface {
private Item item;
private Category category;

public DeleteCommand(Item item, Category category) {


this.item = item;
this.category = category;
}

public void execute() {


item.delete(category);
category.delete(item);
}
}

/**
* Clase invocadora
*
*/
public class ItemManager {
CommandInterface command;

public void setCommand(CommandInterface c) {


command = c;
}

7
Ingeniería del Software II
Unicomfacauca
public void process() {
command.execute();
}
}

/**
* Objeto Cliente
*
*/

public class CommandTest {


public static void main(String[] args) {
//Add an item to the CD category
//create Receiver objects
Item CD = new Item("A Beautiful Mind");
Category catCD = new Category("CD");
//create the command object
CommandInterface command = new AddCommand(CD, catCD);
//create the invoker
ItemManager manager = new ItemManager();
//configure the invoker
//with the command object
manager.setCommand(command);
manager.process();
//Add an item to the CD category
CD = new Item("Duet");
catCD = new Category("CD");
command = new AddCommand(CD, catCD);
manager.setCommand(command);
manager.process();
//Add an item to the New Releases category
CD = new Item("Duet");
catCD = new Category("New Releases");
command = new AddCommand(CD, catCD);
manager.setCommand(command);
manager.process();
//Delete an item from the New Releases category
command = new DeleteCommand(CD, catCD);
manager.setCommand(command);
manager.process();
}
}

También podría gustarte