命令模式(Command Pattern)

本文介绍了命令模式的基本概念、结构,包括抽象命令、具体命令、Invoker和Receiver的角色,以及如何在Java中实现和应用这一设计模式,以解耦请求与处理,优化大规模请求管理。
摘要由CSDN通过智能技术生成

命令模式

说明

命令模式(Command Pattern)属于行为型模式,是将一个请求封装为对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
无论是在现实生活中还是软件系统中,交流是无处不在的,而交流其实就是对命令的请求与处理的过程。当命令的请求者与处理者是一对一或者小规模的多对一时,他们之间的紧耦合是没问题的。但如果是大规模的多对一请求时,对请求命令的管理就成为了需要,否则会造成处理者对请求处理的紊乱,而如果将管理请求命令的职责交给处理者,那么处理者的职责会过于繁重,这时就需要命令模式来管理命令,从而将命令的请求者与处理者进行解耦。
本质:解耦命令请求与处理。

结构

命令模式主要角色如下:
Command(抽象命令角色):定义了执行命令的接口;
ConcreteCommand(具体命令角色):继承/实现Command,实现执行命令的接口,并且需要绑定一个Receiver对象;
Invoker(命令的请求方):命令的请求方,需要定义一个Command的引用,用于接收客户端的命令,并且可以对命令进行管理(记录日志等);
Receiver(命令的接收者):处理具体的命令。
命令模式-类结构图

代码案例

Receiver(命令的接收者)

/**
 * @program: command
 * @description: 命令的接收者
 * @author: wxw
 * @create: 2024-03-11 12:07
 **/
public class Receiver {

    public void buyWahaha(String name, Integer count){
        System.out.println("帮" + name + "购买" + count + "瓶哇哈哈!");
    }

    public void buyHotDog(String name, Integer count){
        System.out.println("帮" + name + "购买" + count + "根热狗!");
    }

    public void buyBread(String name, Integer count){
        System.out.println("帮" + name + "购买" + count + "包面包!");
    }

}

Command(抽象命令角色)

/**
 * @program: command
 * @description: 命令接口
 *               Command(抽象命令角色)
 * @author: wxw
 * @create: 2024-03-11 11:51
 **/
public abstract class BuyCommand {

    protected String name;
    protected Integer count;
    protected Receiver receiver;

    public BuyCommand(String name, Integer count, Receiver receiver) {
        this.name = name;
        this.count = count;
        this.receiver = receiver;
    }

    public abstract String returnCommandName();

    public abstract void execute();
}

ConcreteCommand(具体命令角色)

/**
 * @program: command
 * @description: 购买哇哈哈
 *              ConcreteCommand(具体命令角色)
 * @author: wxw
 * @create: 2024-03-11 12:03
 **/
public class BuyWahaha extends BuyCommand {

    public BuyWahaha(String name, Integer count, Receiver receiver) {
        super(name, count, receiver);
    }

    @Override
    public String returnCommandName() {
        return Commodity.WAHAHA.desc;
    }

    @Override
    public void execute() {
        receiver.buyWahaha(name,count);
    }
}

/**
 * @program: command
 * @description: 购买热狗
 *              ConcreteCommand(具体命令角色)
 * @author: wxw
 * @create: 2024-03-11 12:05
 **/
public class BuyHotDog extends BuyCommand {

    public BuyHotDog(String name, Integer count, Receiver receiver) {
        super(name, count, receiver);
    }

    @Override
    public String returnCommandName() {
        return Commodity.HOT_DOG.desc;
    }

    @Override
    public void execute() {
        receiver.buyHotDog(name,count);
    }

}

/**
 * @program: command
 * @description: 购买面包
 *              ConcreteCommand(具体命令角色)
 * @author: wxw
 * @create: 2024-03-11 12:05
 **/
public class BuyBread extends BuyCommand {

    public BuyBread(String name, Integer count, Receiver receiver) {
        super(name, count, receiver);
    }

    @Override
    public String returnCommandName() {
        return Commodity.BREAD.desc;
    }

    @Override
    public void execute() {
        receiver.buyBread(name,count);
    }

}

Receiver(命令的接收者)

/**
 * @program: command
 * @description: 命令请求者
 * @author: wxw
 * @create: 2024-03-11 12:11
 **/
public class Invoker {

    private List<BuyCommand> commandList = new ArrayList<>();

    // 接收客户端命令
    public void receiveRequest(BuyCommand command) {
        logRecord(command);
        commandList.add(command);
    }

    // 记录日志
    private void logRecord(BuyCommand command){
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sf.format(new Date()) + "记录:" + command.name
                + "需要购买" + command.returnCommandName() + ",数量:" + command.count);
    }

    // 答应详细清单
    public void detailedList(){
        System.out.println("==============购物清单==============");
        Iterator<BuyCommand> iterator = commandList.iterator();
        while(iterator.hasNext()){
            BuyCommand command = iterator.next();
            System.out.println(command.name + ":商品名称:" + command.returnCommandName() + ",数量:" + command.count);
        }
    }

    // 批量执行
    public void sendRequestBatch(){
        System.out.println("===============发送请求==============");
        Iterator<BuyCommand> iterator = commandList.iterator();
        while(iterator.hasNext()){
            BuyCommand command = iterator.next();
            command.execute();
        }
    }

}

枚举常量类

/**
 * @program: command
 * @description: 商品枚举
 * @author: wxw
 * @create: 2024-03-11 15:24
 **/
public enum Commodity {
    WAHAHA("哇哈哈"),
    HOT_DOG("热狗"),
    BREAD("面包")
    ;

    String desc;

    Commodity(String desc) {
        this.desc = desc;
    }
}

客户端

public class Test {

    public static void main(String[] args) {
        // 命令请求者
        Invoker invoker = new Invoker();
        // 命令接收者
        Receiver receiver = new Receiver();

        // 张三需要购买2瓶哇哈哈
        invoker.receiveRequest(new BuyWahaha("张三", 2,  receiver));
        // 李四需要购买1瓶哇哈哈
        invoker.receiveRequest(new BuyWahaha("李四", 1,  receiver));
        // 张三需要购买1根热狗
        invoker.receiveRequest(new BuyHotDog("张三", 1,  receiver));
        // 李四需要购买1包面包
        invoker.receiveRequest(new BuyBread("李四", 1,  receiver));

        // 打印购物清单
        invoker.detailedList();

        // 发送命令请求
        invoker.sendRequestBatch();
    }
}

输出结果

2024-03-11 16:11:05记录:张三需要购买哇哈哈,数量:2
2024-03-11 16:11:05记录:李四需要购买哇哈哈,数量:1
2024-03-11 16:11:05记录:张三需要购买热狗,数量:1
2024-03-11 16:11:05记录:李四需要购买面包,数量:1
==============购物清单==============
张三:商品名称:哇哈哈,数量:2
李四:商品名称:哇哈哈,数量:1
张三:商品名称:热狗,数量:1
李四:商品名称:面包,数量:1
===============发送请求==============
帮张三购买2瓶哇哈哈!
帮李四购买1瓶哇哈哈!
帮张三购买1根热狗!
帮李四购买1包面包!
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值