Modo de comando del modelo de diseño
1. Modo de comando
1.1 Definición y características
El modo de comando se define de la siguiente manera: una solicitud se encapsula como un objeto y la responsabilidad de emitir la solicitud se separa de la responsabilidad de ejecutar la solicitud. De esta manera, los dos se comunican entre sí a través del objeto de comando, que es conveniente para almacenar, transferir, llamar, agregar y administrar el objeto de comando.
Las principales ventajas del modo de comando son las siguientes:
- Reducir el acoplamiento del sistema.
- El modo de comando puede desacoplar el objeto que invoca la operación del objeto que implementa la operación.
- Es muy conveniente agregar o eliminar comandos.
- Agregar y eliminar comandos en el modo comando no afectará a otras clases, cumple con el "principio de apertura y cierre" y es más flexible para la expansión.
- Se pueden implementar comandos macro.
- El modo de comando se puede combinar con el modo combinado para ensamblar múltiples comandos en un comando combinado, que es un comando macro.
- Fácil de implementar operaciones de deshacer y rehacer.
- El modo de comando se puede combinar con el modo memo introducido más adelante para realizar la cancelación y restauración de comandos.
Las desventajas del modo de comando son:
- Se puede generar una gran cantidad de clases de comando específicas.
- Debido a que es necesario diseñar una clase de comando específica para cada operación específica, esto aumentará la complejidad del sistema.
1.2 Estructura del modelo.
El modo de comando incluye los siguientes roles principales:
- Rol de clase de comando abstracto (Comando): declara la interfaz para ejecutar comandos y tiene el método abstracto execute () para ejecutar comandos.
- El rol de comando concreto (
Comando concreto ): es una clase de implementación concreta de la clase de comando abstracto, que tiene el objeto receptor, y completa la operación que debe realizar el comando al llamar a la función del receptor. - El rol del implementador / receptor (receptor): realizar las operaciones relevantes de la función de comando, es el implementador real del negocio de objeto de comando específico.
- Rol Invoker / solicitante (Invoker): es el remitente de la solicitud, generalmente tiene muchos objetos de comando y accede al objeto de comando para realizar solicitudes relacionadas, no accede directamente al receptor.
1.3 Origen del problema
En los sistemas de desarrollo de software, a menudo existe una estrecha relación de acoplamiento entre "solicitantes de métodos" e "implementadores de métodos". Esto no es propicio para la expansión y el mantenimiento de las funciones del software. Por ejemplo, es inconveniente querer realizar "deshacer, rehacer, registrar" y otras acciones sobre el comportamiento, entonces "¿cómo desacoplar el solicitante del método del implementador del método?" Se vuelve muy importante, y el patrón de comando puede resolverse bien Esta pregunta En la vida real, existen muchos ejemplos de este tipo. Por ejemplo, el
ejemplo de código de un control remoto de TV (solicitante de método) TV de control remoto (receptor de comando) es el siguiente:
/**
* @author tbb
* 家用电器类
*/
public abstract class HouseholdElectricalAppliances
{
abstract String kind();
abstract void open();
abstract void close();
}
/**
* @author tbb
* 空调
*/
public class AirConditioning extends HouseholdElectricalAppliances {
@Override
public void open()
{
System.out.println("打开" + kind());
}
@Override
public void close()
{
System.out.println("关闭" + kind());
}
@Override
String kind() {
return "空调";
}
}
/**
* @author tbb
* 电视类
*/
public class Tv extends HouseholdElectricalAppliances
{
@Override
public void open()
{
System.out.println("打开" + kind());
}
@Override
public void close()
{
System.out.println("关闭" + kind());
}
@Override
String kind() {
return "电视";
}
}
/**
* @author tbb
* 控制器
*/
public class Control
{
public void open(HouseholdElectricalAppliances hea)
{
hea.open();
}
public void close(HouseholdElectricalAppliances hea)
{
hea.close();
}
}
public class Test
{
public static void main(String[] args)
{
Tv tv = new Tv();
Control control = new Control();
AirConditioning airConditioning = new AirConditioning();
control.open(tv);
control.close(tv);
control.open(airConditioning);
control.close(airConditioning);
/*
打开电视
关闭电视
打开空调
关闭空调
*/
}
}
1.4 Soluciones
La solución es utilizar el modelo de comando. El primer paso es desacoplar el "solicitante del método" del "implementador del método", como el control remoto de TV (solicitante del método) y el TV de control remoto (implementador de método). El desacoplamiento se divide en el control remoto del televisor (emisor de comandos) para controlar el televisor (receptor de comandos) a través de botones (comandos específicos).
1.5 tipos de UML
1.6 Solución
/**
* @author tbb
* 命令
*/
public interface Command
{
void execute();
}
/**
* @author tbb
* 打开命令
*/
public class OpenCommand implements Command
{
private HouseholdElectricalAppliances hev;
@Override
public void execute()
{
this.hev.open();
}
public OpenCommand(HouseholdElectricalAppliances hev) {
super();
this.hev = hev;
}
}
/**
* @author tbb
* 关闭命令
*/
public class CloseCommand implements Command
{
private HouseholdElectricalAppliances hev;
@Override
public void execute()
{
hev.close();
}
public CloseCommand(HouseholdElectricalAppliances hev) {
super();
this.hev = hev;
}
}
/**
* @author tbb
* 控制器
*/
public abstract class Control
{
abstract void open();
abstract void close();
}
/**
* @author tbb
* 家电类控制器
*/
public class HouseholdElectricalControl extends Control{
private Command openCommand;
private Command closeCommand;
public HouseholdElectricalControl(OpenCommand openCommand,CloseCommand closeCommand) {
super();
this.openCommand = openCommand;
this.closeCommand = closeCommand;
}
@Override
void open()
{
this.openCommand.execute();
}
@Override
void close()
{
this.closeCommand.execute();
}
}
/**
* @author tbb
* 家用电器类
*/
public abstract class HouseholdElectricalAppliances
{
abstract String kind();
abstract void open();
abstract void close();
}
/**
* @author tbb
* 空调
*/
public class AirConditioning extends HouseholdElectricalAppliances {
@Override
public void open()
{
System.out.println("打开" + kind());
}
@Override
public void close()
{
System.out.println("关闭" + kind());
}
@Override
String kind() {
return "空调";
}
}
/**
* @author tbb
* 电视类
*/
public class Tv extends HouseholdElectricalAppliances
{
@Override
public void open()
{
System.out.println("打开" + kind());
}
@Override
public void close()
{
System.out.println("关闭" + kind());
}
@Override
String kind() {
return "电视";
}
}
public class Test
{
public static void main(String[] args)
{
Tv tv = new Tv();
OpenCommand openCommand = new OpenCommand(tv);
CloseCommand closeCommand = new CloseCommand(tv);
HouseholdElectricalControl control = new HouseholdElectricalControl(openCommand, closeCommand);
control.open();
control.close();
AirConditioning airConditioning = new AirConditioning();
openCommand = new OpenCommand(airConditioning);
closeCommand = new CloseCommand(airConditioning);
control = new HouseholdElectricalControl(openCommand, closeCommand);
control.open();
control.close();
/*
打开电视
关闭电视
打开空调
关闭空调
*/
}
}