[Design Pattern Series 22] Ejemplo de patrón de comando y análisis de principio

Descripción general de la serie de patrones de diseño

Patrones de diseño Boleto aereo
Tres modelos de fábrica Entrada de embarque
Modo de estrategia Entrada de embarque
Modo de delegación Entrada de embarque
Patrón de método de plantilla Entrada de embarque
Modo observador Entrada de embarque
Modo singleton Entrada de embarque
Modo de prototipo Entrada de embarque
Modelo de agencia Entrada de embarque
Modo decorador Entrada de embarque
Modo adaptador Entrada de embarque
Modo constructor Entrada de embarque
Modelo de cadena de responsabilidad Entrada de embarque
Modelo de peso mosca Entrada de embarque
Modo de combinación Entrada de embarque
Patrón de fachada Entrada de embarque
Modo Puente Entrada de embarque
Modelo intermediario Entrada de embarque
Modo iterador Entrada de embarque
Modo de estado Entrada de embarque
Modo intérprete Entrada de embarque
Modo de nota Entrada de embarque
Modo de comando Entrada de embarque
Modo visitante Entrada de embarque
Resumen de 7 principios y patrones de diseño de diseño de software Entrada de embarque

Prefacio

Este artículo presentará principalmente el modo de comando y su principio en el modo de diseño, y lo analizará con ejemplos.

Que es el modo de comando

El patrón de comando (patrón de comando) es una encapsulación de comandos, cada comando es una operación. Primero, la parte solicitante envía una solicitud para realizar una operación, y luego la parte receptora recibe la solicitud y realiza la operación.

El modo de comando desacopla al solicitante y el receptor, el solicitante solo necesita enviar el comando sin importar cómo se recibe el comando, cómo se opera el comando y si el comando se ejecuta o no.

El modo de comando es un modo de comportamiento.

¿Por qué necesitas el modo de comando?

En nuestro sistema de desarrollo de software, el solicitante de comportamiento y el ejecutor real suelen tener una relación estrechamente acoplada, pero en este caso, cuando necesitamos modificar el comportamiento, como cancelación o rehacer, solo podemos modificar la solicitud. El modo de comando desacoplará al solicitante y al ejecutor introduciendo una interfaz abstracta entre el solicitante de comportamiento y el ejecutor, de modo que si necesita modificar el comportamiento, solo necesita agregar el comando de comportamiento correspondiente. No es necesario modificar el código fuente del solicitante en absoluto.

De acuerdo, el momento de fingir ha llegado de nuevo: hablar es barato, mostrarle el código , primero veamos un ejemplo muy simple.

Ejemplo de modo de comando

Tomemos la ejecución de los comandos del sistema operativo Linux en XShell como ejemplo para escribir un ejemplo:

1. Primero cree una clase de comando de ejecución real:

package com.zwx.design.pattern.command;

public class LinuxSystem {
    
    
    public void cd(){
    
    
        System.out.println("已经切换到主目录");
    }

    public void ls(){
    
    
        System.out.println("已经列举出当前目录下所有文件");
    }

    public void restart(){
    
    
        System.out.println("开始重启系统");
    }
}

2. Cree una interfaz de comando (orientada a la programación abstracta, por supuesto, puede continuar directamente con el paso 3 en las circunstancias adecuadas):

package com.zwx.design.pattern.command;

public interface ICommand {
    
    
    void execute();
}

3. Hay tres comandos en nuestra clase LinuxSystem anterior, así que a continuación creamos una clase para cada comando Estas clases mantienen un objeto LinuxSystem internamente, que se utiliza para tratar con el ejecutor real LinuxSystem del comando.

clase de comando cd:

package com.zwx.design.pattern.command;

public class CdCommand implements ICommand {
    
    
    private LinuxSystem linuxSystem;

    public CdCommand(LinuxSystem linuxSystem) {
    
    
        this.linuxSystem = linuxSystem;
    }

    @Override
    public void execute() {
    
    
        linuxSystem.cd();
    }
}

ls clase de comando:

package com.zwx.design.pattern.command;

public class LsCommand implements ICommand {
    
    
    private LinuxSystem linuxSystem;

    public LsCommand(LinuxSystem linuxSystem) {
    
    
        this.linuxSystem = linuxSystem;
    }

    @Override
    public void execute() {
    
    
        linuxSystem.ls();
    }
}

Reinicie la clase de comando:

package com.zwx.design.pattern.command;

public class RestartCommand implements ICommand {
    
    
    private LinuxSystem linuxSystem;

    public RestartCommand(LinuxSystem linuxSystem) {
    
    
        this.linuxSystem = linuxSystem;
    }

    @Override
    public void execute() {
    
    
        this.linuxSystem.restart();
    }
}

4. A continuación, también necesitamos una clase para recibir comandos:

package com.zwx.design.pattern.command;

import org.omg.PortableServer.LIFESPAN_POLICY_ID;

import java.util.ArrayList;
import java.util.List;

public class XshellInvoker {
    
    
    private List<ICommand> commandList = new ArrayList<>();

    public XshellInvoker(List<ICommand> commandList) {
    
    
        this.commandList = commandList;
    }

    /**
     * 执行指定命令
     * @param command
     */
    public void execute(ICommand command){
    
    
        command.execute();
    }

    /**
     * 执行命令宏
     */
    public void executeCdAndLs(){
    
    
        for (ICommand command : commandList){
    
    
            if (command instanceof LsCommand || command instanceof CdCommand){
    
    
                command.execute();
            }
        }
    }

    public void executeAll(){
    
    
        for (ICommand command : commandList){
    
    
            command.execute();
        }
    }
}

5. Finalmente, creemos una nueva clase de prueba:

package com.zwx.design.pattern.command;

import java.util.ArrayList;
import java.util.List;

public class TestCommand {
    
    

    public static void main(String[] args) {
    
    
        LinuxSystem linuxSystem = new LinuxSystem();
        List<ICommand> commandList = new ArrayList<>();
        commandList.add(new CdCommand(linuxSystem));
        commandList.add(new LsCommand(linuxSystem));
        commandList.add(new RestartCommand(linuxSystem));

        XshellInvoker xshellInvoker = new XshellInvoker(commandList);

        xshellInvoker.execute(new LsCommand(linuxSystem));//执行指定命令
        System.out.println("------------------------");
        xshellInvoker.executeCdAndLs();//指定特定命令宏
        System.out.println("------------------------");
        xshellInvoker.executeAll();//执行全部命令
    }
}

Los resultados son los siguientes:

已经列举出当前目录下所有文件
------------------------
已经切换到主目录
已经列举出当前目录下所有文件
------------------------
已经切换到主目录
已经列举出当前目录下所有文件
开始重启系统

Lo anterior es una forma estándar de escribir el modo de comando.Como puede ver, debido a que el controlador se ha desacoplado del ejecutor de comando, si desea continuar extendiendo nuevos comandos más adelante, simplemente agregue otra clase de comando.

Rol del modo de comando

Del ejemplo anterior, podemos concluir que el modo iterador tiene principalmente 4 roles:

  • Función de receptor (receptor): responsable de la implementación o ejecución específica de una solicitud (como LinuxSystem en el ejemplo).
  • Función de comando (comando): defina todas las líneas de comando que deben ejecutarse (como ICommand en el ejemplo).
  • Rol de comando específico (ConcreteCommand): Esta clase mantiene un receptor (Receiver) internamente. Después de recibir la solicitud de comando de ejecución, se llama al método correspondiente de Receiver (como CdCommand, LsCommand, RestartCommand en el ejemplo).
  • El rol del solicitante (Invocador): Reciba el comando del cliente y llame al comando correspondiente (como en el ejemplo).

Escenarios de aplicación del modo de comando

De hecho, la idea del modo de comando es desacoplar al solicitante y al implementador del comando a través de un intermediario. Principalmente aplicable a los siguientes escenarios:

  • 1. Hay operaciones con "comandos" en semántica realista, como comandos DOS y comandos de shell.
  • 2. La persona que llama y el receptor de la solicitud deben estar desacoplados para que la persona que llama y el receptor no se llamen directamente entre sí.
  • 3. Los comportamientos que esperan ser ejecutados deben abstraerse, como operaciones de deshacer y recuperar.
  • 4. Es necesario admitir la operación de macro de comandos (es decir, combinación de comandos).

Ventajas y desventajas del modo comando

ventaja:

  • 1. Desacople la solicitud y la implementación mediante la introducción de middleware (interfaz abstracta).
  • 2. Es conveniente expandir, simplemente agregue un objeto directamente agregando un nuevo comando.
  • 3. Admite la operación combinada de comandos, que es más flexible y conveniente.

Desventaja

  • 1. Si hay demasiados comandos, habrá objetos muy grandes.

para resumir

Este artículo presenta principalmente el uso básico del modo de comando y utiliza un ejemplo simple para ayudar a comprender mejor el modo de comando.Finalmente, resume brevemente las ventajas y desventajas de usar el modo de comando.

Por favor, prestame atención y aprende y progresa con el lobo solitario .

Supongo que te gusta

Origin blog.csdn.net/zwx900102/article/details/109352746
Recomendado
Clasificación