Patrones de diseño - el modo de comando (comando)

atención pública Nº JavaStorm para un mayor crecimiento.

Se tarda aproximadamente 6 minutos para leer. Colección tras propuestas de lectura.
El funcionamiento en modo de comando o una solicitud a un objeto empaquetado. El modo de comando permite que el sistema utilice una solicitud diferente de los parámetros del cliente, la cola de peticiones o solicitudes de registro, y puede proporcionar una recuperación comando deshacer.
GitHub Dirección: https://github.com/UniqueDong/zero-design-stu el paquete bajo el código de cabeza.

contorno

El modo de comando del comando se encapsula. El modo de comando para la emisión de una responsabilidad de mando y la responsabilidad de la ejecución de comandos separados, asignados a diferentes objetos.

Cada comando es una operación: la parte solicitante que solicita realizar una operación requerida; parte receptora recibe la solicitud, y lleva a cabo una operación. Modo permite un comando y una de las solicitudes recibidas independientes abierto, por lo que la parte solicitante no tiene que saber la interfaz de uno de la recepción de la solicitud, por no saber cómo se recibió la solicitud, y si se realiza la operación, cuando se llevó a cabo, y cómo el que se ejecuta.

Comando permite una de las partes solicite y reciba solicitudes pueden desprenderse de forma independiente, con el fin de tener las siguientes ventajas:

(1) el modo de comando de modo que el nuevo comando puede añadir fácilmente al sistema.

(2) le permite a uno decidir si la petición recibida es una petición debe ser rechazada.

(3) se pueden diseñar más fácilmente una cola de comandos.

(4) se puede realizar fácilmente a deshacer y solicitud rehacer.

(5) En caso de necesidad, puede ser más fácil de comandos registra.
Diagrama de clases

papel

  • Cliente de papel (Cliente): para crear un ConcreteCommand y establezca su destinatario.
  • (Command) Función: declarar una interfaz para todos los comandos. Llamar al objeto de comando ejecutar método puede permitir que el destinatario realice acciones relacionadas, la interfaz también tiene un método de deshacer compañero de trabajo () retirada.
  • orden específico (ConcreteCommand) Papel: débil acoplamiento entre el receptor y define un comportamiento; implementar el método (), ejecutar es responsable de la operación del receptor de la llamada correspondiente. método de ejecución () generalmente se llama el método de ejecución. La necesidad de llamadas sólo se ejecuta método puede solicitar, y luego una o más acciones invocadas por el ConcreteCommand destinatario.
  • La persona que llama (Invoker) los papeles: la persona que llama para sostener un objeto de comando ejecutar método proporciona un objeto de comando de disparo llamada a un método, se ejecutará el comando.
  • Receptor (receptor) Función: responsable de la implementación y ejecución de una solicitud. Cualquier clase puede ser un receptor, el método de ejecución de la solicitud y se llama el método de acción.

proceso de implementación

  1. El cliente crea un objeto de comando.
  2. SetCommand cliente llama al método en el objeto que llama.
  3. En el siguiente punto apropiado en el tiempo, la persona llama al método del objeto comando de ejecución.
  4. Comando confiada a los destinatarios correspondientes realizadas por la persona que llama. Para completar la tarea.

simulación de la escena

Un versátil control remoto programable 6 ranuras (cada uno de los cuales puede especificar un aparato electrodoméstico diferente), para el control de los aparatos electrodomésticos (TV, acondicionadores de aire, refrigeradores, estéreo). Cada ranura tiene un botón correspondiente [On] y [OFF]. También tiene un botón retirado una llave entera. La demanda es la retirada del caso, como la lámpara está apagada, pulse el botón para encender las luces se abrieron. Ahora bien, si se pulsa el botón Deshacer, entonces la acción se invertirá. Aquí, las luces se apagarán.
control remoto
Aparatos conectados a la ranura correspondiente, la instrucción correspondiente es un interruptor. Cada aparato correspondiente a dos instrucciones, a saber, el botón [abierta] y [OFF].

Muchos aparatos tienen en () y desactivación () método, además de un número de, SETTV (), setVolumn () setTemperature () método.
No podemos escribir si slot1 == Luz continuación light.on () .

la implementación del código

Roles de destinatarios de mando

En primer lugar, tenemos una gran cantidad de aparatos. De hecho, ellos son el público para la ejecución de diferentes comandos.

  • luz
package com.zero.headfirst.command.receiver;

public class Light {
    public void on() {
        System.out.println("打开电灯。");
    }
    public void off() {
        System.out.println("关灯。");
    }
}

  • sonido
package com.zero.headfirst.command.receiver;

public class Stereo {
    public void on() {
        System.out.println("打开音响");
    }

    public void off() {
        System.out.println("关闭音响");
    }

    public void setCD() {
        System.out.println("放入CD");
    }

    public void setVolume() {
        System.out.println("音响音量设置为20");
    }
}

papel de comandos

En primer lugar objeto de comando que implementa esta interfaz, respectivamente, la ejecución de comandos y la retirada

package com.zero.headfirst.command;

/**
 * 命令(Command)角色
 */
public interface Command {
    /**
     * 命令执行
     */
    void execute();

    /**
     * 命令撤销
     */
    void undo();
}

papel comando específico

  • comando definido ilumina para lograr ejecutar. receptor de órdenes tiene una luz de referencia, de manera que cuando la persona llama al delegado para ejecutar las correspondientes luces de la lámpara operación realizada.
package com.zero.headfirst.command.impl;

import com.zero.headfirst.command.Command;
import com.zero.headfirst.command.receiver.Light;

public class LightOnCommand implements Command {

    /**
     * 持有接受者实例,以便当命令execute执行的时候由接受者执行开灯
     */
    private Light light;

    @Override
    public void execute() {
        light.on();
    }

    @Override
    public void undo() {
        light.off();
    }

    /**
     * 设置命令的接受者
     * @param light
     */
    public void setLight(Light light) {
        this.light = light;
    }
}

  • las luces de un comando definido
package com.zero.headfirst.command.impl;

import com.zero.headfirst.command.Command;
import com.zero.headfirst.command.receiver.Light;

public class LightOffCommand implements Command {

    /**
     * 持有接受者实例,以便当命令execute执行的时候由接受者执行
     */
    private Light light;

    @Override
    public void execute() {
        light.off();
    }

    @Override
    public void undo() {
        light.on();
    }

    public void setLight(Light light) {
        this.light = light;
    }
}

  • comando definido sonido abierto
package com.zero.headfirst.command.impl;

import com.zero.headfirst.command.Command;
import com.zero.headfirst.command.receiver.Stereo;

/**
 * 音响开指令
 */
public class StereoOnCommand implements Command {

    private Stereo stereo;

    @Override
    public void execute() {
        stereo.on();
        stereo.setCD();
        stereo.setVolume();
    }

    @Override
    public void undo() {
        stereo.off();
    }

    public void setStereo(Stereo stereo) {
        this.stereo = stereo;
    }
}

  • Cerrar sonido comando definido
package com.zero.headfirst.command.impl;

import com.zero.headfirst.command.Command;
import com.zero.headfirst.command.receiver.Stereo;

public class StereoOffCommand implements Command {

    private Stereo stereo;

    public void setStereo(Stereo stereo) {
        this.stereo = stereo;
    }

    @Override
    public void execute() {
        stereo.off();
    }

    @Override
    public void undo() {
        stereo.on();
        stereo.setCD();
        stereo.setVolume();
    }
}

Otra vuelta restante en el televisor, apague el televisor, encender el aire acondicionado, cierre el aire de no uno a escribir. La plantilla es la misma rutina. Ahora código específico puede dirección de GitHub: https://github.com/UniqueDong/zero-design-stu el paquete bajo el código de cabeza.

El papel de llamadas

De hecho, nuestro mando a distancia.

package com.zero.headfirst.command;

import com.zero.headfirst.command.impl.NoCommand;

import java.util.Arrays;

/**
 * 调用者:遥控器
 */
public class RemoteControl {
    /**
     * 一共4个家电插槽,每个插槽有 开与关命令。
     */
    private Command[] onCommands;
    private Command[] offCommands;

    //用来保存前一个命令,用来实现撤销功能
    private Command undoCommand;

    /**
     * 通过构造器初始化开关数组
     */
    public RemoteControl() {
        onCommands = new Command[4];
        offCommands = new Command[4];
        //初始化所有插槽为空指令
        Command noCommand = new NoCommand();
        for (int i = 0; i < 4; i++) {
            onCommands[i] = noCommand;
            offCommands[i] = noCommand;
        }
        //一开始没有所谓的前一个命令,所以默认无指令
        undoCommand = noCommand;
    }

    /**
     * 设置指定插槽对应的按钮指令
     * @param slot 插槽位置
     * @param onCommand 开指令
     * @param offCaommand 关指令
     */
    public void setCommand(int slot,Command onCommand, Command offCaommand) {
        onCommands[slot] = onCommand;
        offCommands[slot] = offCaommand;
    }

    /**
     * 模拟按下指定插槽对应的【开】按键
     */
    public void pressOnButton(int slot) {
        onCommands[slot].execute();
        //将当前指令记录下来,用于在撤销的时候能执行命令对应的 undo 方法从而实现撤销功能
        undoCommand = onCommands[slot];
    }

    /**
     * 模拟按下指定插槽对应的【关】按键
     */
    public void pressOffButton(int slot) {
        offCommands[slot].execute();
        undoCommand = offCommands[slot];
    }

    /**
     * 撤销功能
     */
    public void pressUndoButton() {
        undoCommand.undo();
    }

    @Override
    public String toString() {
        return "RemoteControl{" +
                "onCommands=" + Arrays.toString(onCommands) +
                ", offCommands=" + Arrays.toString(offCommands) +
                '}';
    }
}

rol de cliente

La obtención de mando a distancia, y para conseguir las luces, el aire acondicionado receptor de órdenes. [Crear la abertura correspondiente, respectivamente], comando [fuera].
Enlace a la ranura correspondiente. Cuando el botón se pulsa el disparador de las instrucciones especificadas.

package com.zero.headfirst.command;

import com.zero.headfirst.command.impl.*;
import com.zero.headfirst.command.receiver.AirConditioning;
import com.zero.headfirst.command.receiver.Light;
import com.zero.headfirst.command.receiver.Stereo;
import com.zero.headfirst.command.receiver.TV;

/**
 * 客户端角色
 */
public class CommandClient {
    public static void main(String[] args) {
        //创建一个遥控器-调用者角色
        RemoteControl remoteControl = new RemoteControl();
        //1. 创建电灯-接受者角色
        Light light = new Light();
        //创建开灯、关灯命令-命令具体角色
        LightOnCommand lightOnCommand = new LightOnCommand();
        lightOnCommand.setLight(light);
        LightOffCommand lightOffCommand = new LightOffCommand();
        lightOffCommand.setLight(light);

        //调用者设置电灯插槽以及对应的开关按键指令-调用者角色
        remoteControl.setCommand(0, lightOnCommand, lightOffCommand);

        // 2. 设置音响插槽与对应按键指令
        Stereo stereo = new Stereo();
        StereoOnCommand stereoOnCommand = new StereoOnCommand();
        stereoOnCommand.setStereo(stereo);
        StereoOffCommand stereoOffCommand = new StereoOffCommand();
        stereoOffCommand.setStereo(stereo);

        remoteControl.setCommand(1, stereoOnCommand, stereoOffCommand);

        //3. 空调
        AirConditioning airConditioning = new AirConditioning();
        AirConditioningOnCommand airConditioningOnCommand = new AirConditioningOnCommand();
        airConditioningOnCommand.setAirConditioning(airConditioning);
        AirConditioningOffCommand airConditioningOffCommand = new AirConditioningOffCommand();
        airConditioningOffCommand.setAirConditioning(airConditioning);

        remoteControl.setCommand(2, airConditioningOnCommand, airConditioningOffCommand);

        //4. 电视
        TV tv = new TV();
        TVOnCommand tvOnCommand = new TVOnCommand();
        tvOnCommand.setTv(tv);
        TVOffCommand tvOffCommand = new TVOffCommand();
        tvOffCommand.setTv(tv);

        remoteControl.setCommand(3, tvOnCommand, tvOffCommand);

        //模拟按键
        System.out.println("-------码农回家了,使用遥控开启电灯、音响、空调、电视----");
        remoteControl.pressOnButton(0);
        remoteControl.pressOnButton(1);
        remoteControl.pressOnButton(2);
        remoteControl.pressOnButton(3);

        System.out.println("------码农睡觉了,使用遥控关闭电灯、音响、电视。不关空调--------");
        remoteControl.pressOffButton(0);
        remoteControl.pressOffButton(1);
        remoteControl.pressOffButton(3);

        System.out.println("----撤销测试,先打开电灯。再关闭电灯。然后按撤销----");
        remoteControl.pressOnButton(0);
        remoteControl.pressOffButton(0);
        //一键撤销
        remoteControl.pressUndoButton();
    }
}

resultados de la prueba

-------码农回家了,使用遥控开启电灯、音响、空调、电视----
打开电灯。
打开音响
放入CD
音响音量设置为20
打开空调
空调温度设置28°
打开电视
设置频道为宇宙电视台
电视音量设置为20
------码农睡觉了,使用遥控关闭电灯、音响、电视。不关空调--------
关灯。
关闭音响
关闭电视
----撤销测试,先打开电灯。再关闭电灯。然后按撤销----
打开电灯。
关灯。
打开电灯。

resumen

escenarios de uso:

  1. cola de trabajo: uno de los extremos de la instrucción Además, el objetivo se consigue siempre que el modo de comando se puede poner en la cola. El otro extremo es el hilo. Hilo procede siguientes trabajos: un comando de la cola, y luego ejecutar método se llama, la llamada se descarta después del comando, y luego continuar a eliminar un comando.
  2. grupo de subprocesos.

No hay modo de JavaStorm más atención pública

Aquí Insertar imagen Descripción

Publicado 28 artículos originales · ganado elogios 2 · Vistas 1470

Supongo que te gusta

Origin blog.csdn.net/qq_14855971/article/details/92098100
Recomendado
Clasificación