18【命令设计模式】

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 18【命令设计模式】,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文


十八、命令设计模式

18.1 命令设计模式简介

18.1.1 命令设计模式概述

命令设计模式(Command Pattern):命令模式是对命令的封装,将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。命令模式解耦了请求方和接收方,请求方只需要请求执行命令,不需要关心命令怎样被接收,怎样被操作以及是否被执行等;


在软件系统中,请求者与执行者通常是一种紧耦合关系,因为这些实现起来简单明了,但紧耦合的关系伴随着缺乏扩展性。在某些场合中,当对行为进行修改时必定要修改源代码。

而命令模式通过请求域实现间引入一个抽象命令接口,解耦和请求与实现,并且命令接口是抽象的,他由不同的子类实现,因此具备扩展性。命令模式的本质就是解耦命令与执行者;

18.1.2 命令设计模式的UML类图

命令设计模式主要包含如下4个角色:

  • 1)接收者角色(Receiver):负责具体执行一个请求
  • 2)抽象命令角色(ICommand):规范需要执行所有的命令行为
  • 3)具体命令角色(ConcreteCommand):实现具体命令,其内部维护一个Receiver角色,具体功能交给Receiver实现
  • 4)请求角色(Invoker):接收客户端命令,并执行命令;

在这里插入图片描述

18.2 命令设计模式的实现

【案例】

设计一个点餐场景,客户把订单交给服务员,服务员将客户需求交给后厨,后厨接收到订单需求后开始做菜;

  • 订单:命令(Command)
  • 服务员:命令的发送者(Invoker)
  • 后厨:命令接收者(Receiver)

  • 1)命令接收者:
package com.pattern.demo01_手动实现观察者设计模式;

/**
 * @author lscl
 * @version 1.0
 * @intro: 厨师(命令接收者)
 */
public class CookReceiver {
    public void menu1(){
        System.out.println("厨师接到指令......");
        System.out.println("炒了一盘辣椒炒肉~");
        System.out.println("--------------------");
    }

    public void menu2(){
        System.out.println("厨师接到指令......");
        System.out.println("炒了一盘粉蒸肉~");
        System.out.println("--------------------");
    }

    public void menu3(){
        System.out.println("厨师接到指令......");
        System.out.println("炒了一盘藜蒿腊肉~");
        System.out.println("--------------------");
    }
}
  • 2)抽象命令:
package com.pattern.demo01_手动实现观察者设计模式;

/**
 * @author lscl
 * @version 1.0
 * @intro: 抽象菜单,规范客户要点的菜(命令角色,规范客户端能请求什么命令)
 */
public interface IMenuCommand {
    void command();
}
  • 3)具体命令-1:
package com.pattern.demo01_手动实现观察者设计模式;

/**
 * @author lscl
 * @version 1.0
 * @intro: 具体菜单(具体命令角色)
 */
public class Menu1Command implements IMenuCommand{

    // 包含命令执行接收者(用于执行具体的命令)
    private CookReceiver cookReceiver;

    public Menu1Command(CookReceiver cookReceiver) {
        this.cookReceiver = cookReceiver;
    }

    @Override
    public void command() {
        // 最终还是接收者来执行具体的命令(最终还是厨师来炒菜)
        cookReceiver.menu1();
    }
}
  • 4)具体命令-2:
package com.pattern.demo01_手动实现观察者设计模式;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Menu2Command implements IMenuCommand {
    // 包含命令执行接收者(用于执行具体的命令)
    private CookReceiver cookReceiver;

    public Menu2Command(CookReceiver cookReceiver) {
        this.cookReceiver = cookReceiver;
    }

    @Override
    public void command() {
        cookReceiver.menu2();
    }
}
  • 5)命令请求/发送者:
package com.pattern.demo01_手动实现观察者设计模式;

/**
 * @author lscl
 * @version 1.0
 * @intro: 服务员,接收客人的请求(命令请求者,接收客户端的指令)
 */
public class WaiterInvoker {

    // 服务员具具备发送请求功能,发送请求给厨师进行炒菜
    private IMenuCommand menuCommand;

    public WaiterInvoker(IMenuCommand menuCommand) {
        this.menuCommand = menuCommand;
    }

    public void execute(){
        // 最终把命令发送给厨师
        menuCommand.command();
    }

}
  • 6)测试代码:
package com.pattern.demo01_手动实现观察者设计模式;

/**
 * @author lscl
 * @version 1.0
 * @intro:
 */
public class Demo01 {
    public static void main(String[] args) {

        // 创建一个厨师(命令接收者,最终由厨师来执行命令)
        CookReceiver cookReceiver=new CookReceiver();

        // 创建一个服务员(命令请求者,由服务员来发送命令)
        WaiterInvoker waiterInvoker=new WaiterInvoker(new Menu1Command(cookReceiver));
        waiterInvoker.execute();

        waiterInvoker=new WaiterInvoker(new Menu2Command(cookReceiver));
        waiterInvoker.execute();
    }
}

18.3 命令设计模式的优缺点

  • 优点:
    • 1)解耦了命令请求与实现
    • 2)可以在现有命令的基础上,增加额外功能,结合装饰模式会更加灵活
  • 缺点:
    • 1)使用命令模式造成具体命令类增多,系统结构更加复杂

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/131685.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!