设计模式 - 命令模式

一、基本介绍

  • 英文名:Command
  • 概念:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能
  • 模式类型:结构型
  • 设计原则:
  • 主要特点:

二、实现

需求: 开发项目的需求变更

  • 需要修改需求文档、调整页面、更改代码等
1、一般实现
Ⅰ、代码
public interface Group {
    //甲乙双方分开办公,如果你要和某个组讨论,你首先要找到这个组
    void find();

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

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

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

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

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

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

    // ...省略其余方法实现 
}

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

    @Override
    public void add() {
        System.out.println("客户要求增加一项功能...");
    }
    
    // ...省略其余方法实现
}

public class Client {
    public static void main(String[] args) {
        //首先客户找到需求组说,过来谈需求,并修改
		System.out.println("-----------客户要求增加一项需求---------------"); 
        Group rg = new RequirementGroup(); 
        //找到需求组 
        rg.find(); 
        //增加一个需求 
        rg.add(); 
        //要求变更计划 
        rg.plan();
    }
}
Ⅱ、优点
Ⅲ、缺点
  • 每一个命令的执行都需要挨个找寻执行者,且需要清楚命令执行的步骤
2、模式
  • Receive接收者角色

    该角色就是干活的角色,命令传递到这里是应该被执行的

  • Command命令角色

    需要执行的所有命令都在这里声明

  • Invoker调用者角色

    接收到命令,并执行命令
    在这里插入图片描述

Ⅰ、代码
抽象接收者
public interface Group {
    //甲乙双方分开办公,如果你要和某个组讨论,你首先要找到这个组
    void find();

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

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

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

    //被要求给出所有的变更计划
    void plan();
}
具体接收者
public class RequirementGroup implements Group {
    @Override
    public void find() {
        System.out.println("找到需求组...");
    }

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

    // ...省略其余方法实现 
}

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

    @Override
    public void add() {
        System.out.println("客户要求增加一项功能...");
    }
    
    // ...省略其余方法实现
}
抽象命令
public abstract class Command {
    // 聚合接收者
    protected Group group;

    public Command(Group group) {
        this.group = group;
    }

    public abstract void execute();
}
具体命令
public class AddRequirementCommand extends Command {

    // 具体命令默认聚合该命令的执行者
    public AddRequirementCommand() {
        super(new RequirementGroup());
    }

    public AddRequirementCommand(Group group) {
        super(group);
    }

    @Override
    public void execute() {
        super.group.find();
        super.group.add();
    }
}

public class AddCodeCommand extends Command {

    public AddCodeCommand() {
        super(new CodeGroup());
    }

    public AddCodeCommand(Group group) {
        super(group);
    }

    @Override
    public void execute() {
        super.group.find();
        super.group.add();
    }
}
调用者
public class Invoker {

    private Command command;

    // 执行命令
    public void action() {
        this.command.execute();
    }

    public Command getCommand() {
        return command;
    }

    public void setCommand(Command command) {
        this.command = command;
    }
}
场景
public class Client {
    public static void main(String[] args) {
        Invoker invoker = new Invoker();
        Command command = new AddRequirementCommand();
        invoker.setCommand(command);
        invoker.action();
    }
}
Ⅱ、优点
  • 类间解耦

    调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command抽象类的execute方法就可以,不需要了解到底是哪个接收者执行

  • 可扩展性

    Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严 重的代码耦合

  • 命令模式结合其他模式会更优秀

    命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少Command子类的膨胀问题

Ⅲ、缺点
  • 如果有N个命令,Command的子类就可不是几个,而是N个,这个类膨胀得非常大,这个就需要在项目中慎重考虑使用

三、使用场景

1、常见应用场景
Ⅰ、
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值