[Patrón de diseño de Java] Patrón de diseño de Java (6) Patrón de comando (Patrón de comando)

Contenido de este artículo

1. Introducción al modo de comando

Dos, implementación de código

2.1 Diagrama general de clases

2.2 Implementación del código


El patrón de comando (patrón de comando) es un patrón de diseño basado en datos, que es un patrón de comportamiento. La solicitud se envuelve en el objeto en forma de comando y se pasa al objeto que realiza la llamada. El objeto que llama busca un objeto adecuado que pueda manejar el comando y pasa el comando al objeto correspondiente, que ejecuta el comando.

1. Introducción al modo de comando

Intención: encapsular una solicitud en un objeto para que pueda parametrizar clientes con diferentes solicitudes.

Solución principal: en el sistema de software, el solicitante de comportamiento y el implementador de comportamiento suelen estar en una relación estrechamente acoplada, pero en algunos casos, como cuando el comportamiento debe registrarse, cancelarse o rehacerse, y las transacciones se procesan, esto no puede ser resistido Variar el diseño fuertemente acoplado no es adecuado.

Cuándo usarlo: en algunas situaciones, como "grabar, deshacer / rehacer, transacción" y otros procesos de comportamiento, este tipo de acoplamiento estrecho que no puede resistir los cambios es inapropiado. En este caso, ¿cómo desacoplar el "solicitante de comportamiento" del "implementador de comportamiento"? La abstracción de un conjunto de comportamientos como objetos puede lograr un acoplamiento flexible entre los dos.

Cómo resolverlo: llamar al receptor para ejecutar el comando a través del llamador, el orden es: llamador → comando → receptor.

Código clave: Defina tres roles: 1. Recibió el objeto de ejecución del comando real 2. Comando 3. El invocador usa la entrada del objeto de comando

Ejemplo de aplicación: solo hay un controlador central de acción ActionServlet en struts 1, que es equivalente a Invoker, y las clases de capa de modelo tendrán diferentes clases de modelo con diferentes aplicaciones, que son equivalentes a comandos específicos.

Ventajas: 1. Reducir el grado de acoplamiento del sistema. 2. Se pueden agregar fácilmente nuevos comandos al sistema.

Desventajas: el uso del modo de comando puede causar demasiadas clases de comando específicas en algunos sistemas.

Escenario de uso: el modo de comando se puede utilizar siempre que se considere un comando, como por ejemplo: 1. Cada botón de la GUI es un comando. 2. Simular CMD.

Nota: El sistema debe admitir la operación de deshacer (Deshacer) y la operación de rehacer del comando. También puede considerar el uso del modo de comando. Consulte la extensión del modo de comando.

Dos, implementación de código

Los ejemplos de implementación de código de todos los patrones de diseño se pueden ver en Code Cloud. Si está interesado, puede verificarlo. Dirección de Code Cloud: https://gitee.com/no8g/java-design-patterns

2.1 Diagrama general de clases

En este diagrama de clases, vemos tres roles:

Función del receptor: esta es la función del trabajo. El comando debe ejecutarse cuando se le pasa. Específicamente, en nuestro ejemplo anterior, hay tres clases de implementación de Grupo;

Función de comando: es un comando, todos los comandos que debo ejecutar se declaran aquí;

Rol de invocador: la persona que llama, recibe el comando y ejecuta el comando En el ejemplo, mi gerente de proyecto es este rol;

El modo de comando es relativamente simple, pero se usa con mucha frecuencia en proyectos, y la encapsulación es muy buena, porque separa al solicitante (Invoker) del ejecutor (Receiver), y la escalabilidad también está bien garantizada. Sin embargo, el modo de comando también tiene sus deficiencias. Puedes ver si no hay subclases de Comando. Si quiero anotar no pocas, sino decenas, este tipo de expansión es mucho, y esto requiere a todos en el proyecto. Considere usarlo.

2.2 Implementación del código

package com.iot.practice.designpattern.command.commandpattern;

/**
 * <p>CommandClient 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 15:45</p>
 * <p>@remark:</p>
 */
public class CommandClient {

    public static void main(String[] args) {
        // 定义我们的接头人
        Invoker zhangSan = new Invoker();

        // 客户要求增加一项需求
        System.out.println("\n-------------客户要求增加一项需求-----------------");

        // 客户给我们下命令来
        Command command = new AddRequirementCommand();

        // 接头人接收到命令
        zhangSan.setCommand(command);

        // 接头人执行命令
        zhangSan.action();


        // 客户要求增加一项需求
        System.out.println("\n-------------客户要求删除一个页面-----------------");
        // 客户给我们下命令来
        Command command1 = new DeletePageCommand();

        //接头人接收到命令
        zhangSan.setCommand(command1);

        //接头人执行命令
        zhangSan.action();
    }
}
package com.iot.practice.designpattern.command.commandpattern;

import com.iot.practice.designpattern.command.CodeGroup;
import com.iot.practice.designpattern.command.PageGroup;
import com.iot.practice.designpattern.command.RequirementGroup;

/**
 * <p>Command 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 15:34</p>
 * <p>@remark:命令的抽象类,我们把客户发出的命令定义成一个一个的对象</p>
 */
public abstract class Command {

    /**
     * 把三个组都定义好,子类可以直接使用
     *
     * 需求组
     */
    protected RequirementGroup requirementGroup = new RequirementGroup();

    /**
     * 美工组
     */
    protected PageGroup pageGroup = new PageGroup();

    /**
     * 代码组
     */
    protected CodeGroup codeGroup = new CodeGroup();

    /**
     * 只要一个方法,你要我做什么事情
     */
    public abstract void execute();
}
package com.iot.practice.designpattern.command.commandpattern;

/**
 * <p>Invoker 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 15:42</p>
 * <p>@remark:接头人的职责就是接收命令,并执行</p>
 */
public class Invoker {

    /**
     * 什么命令
     */
    private Command command;

    /**
     * 客户发出命令
     */
    public void setCommand(Command command) {
        this.command = command;
    }

    /**
     * 执行客户的命令
     */
    public void action() {
        this.command.execute();
    }
}
package com.iot.practice.designpattern.command.commandpattern;

/**
 * <p>AddRequirementCommand 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 15:38</p>
 * <p>@remark:增加一项需求</p>
 */
public class AddRequirementCommand extends Command {

    /**
     * 执行增加一项需求的命令
     */
    @Override
    public void execute() {
        // 找到需求组
        super.requirementGroup.find();

        // 增加一份需求
        super.requirementGroup.add();

        // 给出计划
        super.requirementGroup.plan();
    }
}
package com.iot.practice.designpattern.command.commandpattern;

/**
 * <p>DeleltePageCommand 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 15:41</p>
 * <p>@remark:<删除一个页面的命令/p>
 */
public class DeletePageCommand extends Command {

    /**
     * 执行删除一个页面的命令
     */
    @Override
    public void execute() {
        // 找到页面组
        super.pageGroup.find();
        // 删除一个页面
        super.pageGroup.delete();
        // 给出计划
        super.pageGroup.plan();
    }
}
package com.iot.practice.designpattern.command;

/**
 * <p>Group 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 15:11</p>
 * <p>@remark:项目组分成了三个组,每个组还是要接受增删改的命令</p>
 */
public abstract class Group {

    /**
     * 甲乙双方分开办公,你要和那个组讨论,你首先要找到这个组
     */
    public abstract void find();

    /**
     * 被要求增加功能
     */
    public abstract void add();

    /**
     * 被要求删除功能
     */
    public abstract void delete();

    /**
     * 被要求修改功能
     */
    public abstract void change();

    /**
     * 被要求给出所有的变更计划
     */
    public abstract void plan();
}

 

package com.iot.practice.designpattern.command;

/**
 * <p>RequirementGroup 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 15:14</p>
 * <p>@remark:</p>
 */
public class RequirementGroup extends Group {

    @Override
    public void find() {
        System.out.println("找到需求组...");
    }

    @Override
    public void add() {
        System.out.println("客户要求增加一项需求...");
    }

    @Override
    public void delete() {
        System.out.println("客户要求删除一项需求...");
    }

    @Override
    public void change() {
        System.out.println("客户要求修改一项需求...");
    }

    @Override
    public void plan() {
        System.out.println("客户要求需求变更计划...");
    }
}
package com.iot.practice.designpattern.command;

/**
 * <p>PageGroup 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 15:23</p>
 * <p>@remark:美工组的职责是设计出一套漂亮、简单、便捷的界面</p>
 */
public class PageGroup extends Group {

    @Override
    public void find() {
        System.out.println("找到美工组...");
    }

    @Override
    public void add() {
        System.out.println("客户要求增加一个页面...");
    }

    @Override
    public void delete() {
        System.out.println("客户要求删除一个页面...");
    }

    @Override
    public void change() {
        System.out.println("客户要求修改一个页面...");
    }

    @Override
    public void plan() {
        System.out.println("客户要求页面变更计划...");
    }
}
package com.iot.practice.designpattern.command;

/**
 * <p>CodeGroup 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 15:27</p>
 * <p>@remark:代码组的职责是实现业务逻辑,当然包括数据库设计了</p>
 */
public class CodeGroup extends Group {

    @Override
    public void find() {
        System.out.println("找到代码组...");
    }

    @Override
    public void add() {
        System.out.println("客户要求增加一项功能...");
    }

    @Override
    public void delete() {
        System.out.println("客户要求删除一项功能...");
    }

    @Override
    public void change() {
        System.out.println("客户要求修改一项功能...");
    }

    @Override
    public void plan() {
        System.out.println("客户要求代码变更计划...");
    }
}

 

 

¡fin!

Supongo que te gusta

Origin blog.csdn.net/weixin_44299027/article/details/113888194
Recomendado
Clasificación