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