设计模式——命令模式

  相关链接:

【设计模式】专栏:【设计模式】专栏

相关例子可下载: Java常用设计模式例子

命令模式

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

优点

  • 通过引入中间件(抽象接口),降低系统的耦合度

  • 扩展性良好,增加 / 删除 命令时非常方便,不影响其他类,满足“开-闭原则”

缺点

  • 可能产生大量的具体命令类。因为每一个具体操作都需要设计一个具体命令类,这会增加系统的复杂性

  • 命令模式的结果其实就是接收方的执行结果,但是为了以命令的形式进行架构、解耦请求与实现,引入了额外类型结构(引入了请求方与抽象命令接口),增加了理解上的困难。不过这也是设计模式的通病,抽象必然会额外增加类的数量,代码抽离肯定比代码聚合更加难理解。

命令模式的角色

命令模式可以将系统中的相关操作抽象成命令,使调用者与实现者相关分离。

命令模式包含的主要角色如下:

抽象命令类(Command)角色

声明执行命令的接口,拥有执行命令的抽象方法 execute()

具体命令类(Concrete Command)角色

是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。

实现者/接收者(Receiver)角色

执行命令功能的相关操作,是具体命令对象业务的真正实现者。

调用者/请求者(Invoker)角色

是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

示例代码

实现者/接收者

因为考虑到可能会存在多个接收者,有多个就需要定义一个所有特性的抽象集合——抽象的接收者

/**
 * 命令模式——实现者/接收者角色
 *
 * (定义一个抽象接收者,因为接收者可能有多个)
 *
 */
public abstract class Receiver {
    /**
     * 抽象接收者,定义每个接收者必须完成的任务
     */
    public abstract void doSomeThing();

}

其具体的接收者代码如下:

/**
 * 命令模式——实现者/接收者角色
 *
 * (定义具体接收者)
 *
 */
public class ConcreteReciver1 extends Receiver{
    @Override
    public void doSomeThing() {
        System.out.println("接收者1干活了");
    }
}

/**
 * 命令模式——实现者/接收者角色
 *
 * (定义具体接收者)
 *
 */
public class ConcreteReciver2 extends Receiver{
    @Override
    public void doSomeThing() {
        System.out.println("接收者2干活了");
    }
}

抽象命令类

/**
 * 命令模式——抽象命令类
 *
 */
public abstract class Command {

    /**
     * 执行命令,每个命令都必须要执行
     */
    public abstract void execute();
}

具体命令类

/**
 * 命令模式——具体命令类
 *
 */
public class ConcreteCommand1 extends Command{

    // 构建接收者对象
    private Receiver receiver;

    /**
     * 构造函数,指定接收者
     * @param receiver
     */
    public ConcreteCommand1(Receiver receiver) {
        this.receiver = receiver;
    }

    /**
     * 执行命令
     */
    @Override
    public void execute() {
        // 接收者完成任务
        this.receiver.doSomeThing();
    }
}
/**
 * 命令模式——具体命令类
 *
 */
public class ConcreteCommand2 extends Command{

    // 构建接收者对象
    private Receiver receiver;

    /**
     * 构造函数,指定接收者
     * @param receiver
     */
    public ConcreteCommand2(Receiver receiver) {
        this.receiver = receiver;
    }

    /**
     * 执行命令
     */
    @Override
    public void execute() {
        // 接收者完成任务
        this.receiver.doSomeThing();
    }
}

调用者/请求者

/**
 * 命令模式——调用者
 *
 */
public class Invoker {
    // 构建命令对象
    private List<Command> commands = new ArrayList<>();

    /**
     * 指定要执行的命令
     * @param command
     */
    public void setCommand(Command command) {
        commands.add(command);
    }

    /**
     * 执行命令
     */
    public void action() {
        // 循环执行所有命令
        commands.forEach(command -> {
            command.execute();
        });
        // 清除已执行的命令
        commands.clear();
    }
}

测试类

/**
 * 命令模式
 *
 */
public class CommandPatternDemo {

    public static void main(String[] args) {
        // 声明调用者Invoker
        Invoker invoker = new Invoker();
        // 定义接收者1
        Receiver receiver1 = new ConcreteReciver1();
        Receiver receiver2 = new ConcreteReciver2();
        // 定义命令1,并将该命令指定发送给接收者1
        Command command1 = new ConcreteCommand1(receiver1);
        Command command2 = new ConcreteCommand2(receiver2);
        // 把命令交给调用者去执行
        invoker.setCommand(command1);
        invoker.setCommand(command2);
        invoker.action();
    }

}

  结束语

1、更多设计模式内容请看【设计模式】专栏

2、相关例子代码可下载: Java常用设计模式例子

PS:  【 Java常用设计模式例子 】 内已包含 【设计模式】专栏 里所涉及的代码,需要代码的同学可以下载哦,如果之前已下载过的同学,就不需要重复下载啦~

以上内容如有不正确或需要补充的地方,还请多多请教,会及时更新改正~

欢迎评论~ 感谢点赞~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值