Patrón de diseño Command

Mas que nada quise postear sobre este patrón de diseño, ya que en un reciente proyecto donde el requerimiento era utilizar RMI, al usarlo me pareció estupendo, ya que en lugar de crear varias interfaces y estarlas registrando, solo fue necesario crear una sobre la cual se centraba y administraba la ejecución de acciones. En este patrón existen varias clases que juegan un papel importante: Invoker, o el cliente que realiza la petición de ejecutar la acción; CommandManager, quien administra y controla la ejecución de acciones; AbstractCommand, como clase común para todas las acciones concretas y por ultimo ConcreteCommand, que es la implemetancion de cada acción.

A continuación muestro el diagrama de clases utilizado


Sesion.java

public class Sesion {
...
public Parametro ejecutar(Parametro p) throws AvException {
			try {
				p.setUsername(usuario.getUser());
				Parametro out = RemoteStubCache.getStubToRemoteObject(host).ejecutar(
							p);

				return out;
			} catch (RemoteException e) {
				throw new AvException(
						"Ha occurrido un error al intentar ejecutar "
								+ "la accion :" + p.getAccion(), e);
			}
		}// ejecutar
}//Sesion

Como CommandManager e implementando una interfaz para exponer métodos con RMI:

ServerRemoteImpl.java

public class ServerRemoteImpl implements ServerRemote, Unreferenced {
...
	public Parametro ejecutar(Parametro param) throws RemoteException {
		log.info("Inicio - ejecutar(Parametro param)");

		BaseAccion accion = BaseAccion.getAccion(param.getAccion());
		Parametro p = null;
		if (accion != null) {
			log.debug("Ejecutar : " + param.getAccion());
			try {
				p = accion.ejecutar(param);
			} catch (AvException e) {
				log
						.error("Ha ocurrido un error al intentar ejecutar la accion");
				throw new RemoteException("Ha ocurrido un error al intentar "
						+ "ejecutar la accion", e);
			}
		} else {
			log.warn("Accion no encontrada");
		}

		log.info("Fin - ejecutar(Parametro param)");

		return p;
	}// ejecutar
}// ServerRemoteImpl

En cuanto a AbstractCommand, cabe notar que agregue métodos para obtener las acciones y beans, estos métodos se basan en clases de Spring:

BaseAccion.java

public abstract class BaseAccion {
...

	public static Object getBean(String bean) {
		return getContext().getBean(bean);
	}// getBean

	public static BaseAccion getAccion(String accion) {
		if (accion != null && accion.trim().length() > 0) {
			return (BaseAccion) getContext().getBean(accion);
		}
		return null;
	}// getAccion

	public abstract Parametro ejecutar(Parametro parametro) throws AvException;
}// BaseAccion

Y por ultimo un ejemplo de alguna acción concreta o ConcreteCommand, que en este caso corresponde a la acción de agregar un usuario

AgregarAccion.java

public class AgregarAccion extends BaseAccion {

	private static Logger log = Logger.getLogger(AgregarAccion.class);

	@Override
	public Parametro ejecutar(Parametro parametro) throws AvException {
		log.info("Inicio - ejecutar(Parametro parametro)");

		UsuarioLayer ul = (UsuarioLayer) getBean(UsuarioLayer.BEAN_NAME);
		Usuario u = null;
		if (parametro.getValor(Tipo.INPUT) instanceof Usuario) {
			u = (Usuario) parametro.getValor(Tipo.INPUT);
			ul.agregar(u);
			parametro.setValor(Tipo.OUTPUT, u);
		}

		log.info("Fin - ejecutar(Parametro parametro)");

		return parametro;
	}// ejecutar
}// AgregarAccion