设计模式之命令模式

定义: 将请求封装成对象,使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销或者恢复功能。命令模式是一种行为型设计模式。
角色模型:

  • 抽象命令角色模型: 一个声明了所有具体命令类的抽象接口,定义需要执行的命令;
  • 具体命令角色模型: 持有接收者实例,实现命令方法,在方法内调用接收者的行为;
  • 调用者: 负责调用命令对象执行请求;
  • 接收者: 负责具体执行请求;

下面是一个使用命令模式设计的简单例子:
场景需求: 在学生时期,有各种课程与若干课代表。现在需要检查所有课程的作业,班主任需要收集学生所有课程的作业情况,由各课任老师上报各课程作业情况,课任老师就要求自己的课代表负责检查,统一上报检查情况。
分析: 这里可以分析出这么一个命令链: 班主任 -> 课任老师 -> 课代表 -> 普通学生。班主任要看作业情况,这是请求;检查作业这是实现。最终场景与角色模型的对应关系就是:抽象命令是检查作业;具体命令是每一门课程的作业;调用者是班主任;接收者是课代表。依次用代码设计出来:

//抽象命令角色(检查作业这一回事)
public interface Task {
    void checkTask();
}

因为在具体命令角色里会持有接收者实例,所以具体命令放到最后来定义,先把调用者跟接收者先创建出来:

//调用者(班主任)
public class HeadTeacher {

    private Task task;

    public HeadTeacher(Task task) {
        this.task = task;
    }

    /**
     *为了能够切换执行不同命令
     */
    public void setTask(Task task){
        this.task = task;
    }

    public void checkTask() {
        task.checkTask();
    }
}
//接收者(课代表),实际执行请求的人
public class ClassRepresentatives {

    public void checkChinese(){
        Log.d("tag", "检查了语文作业");
    }

    public void checkMath(){
        Log.d("tag", "检查了数学作业");
    }

}

接下来分别是具体命令:

//检查语文作业
public class ChineseTask implements Task {

    private ClassRepresentatives representatives;

    public ChineseTask() {
        representatives = new ClassRepresentatives();
    }

    @Override
    public void checkTask() {
        representatives.checkChinese();
    }
}

//检查数学作业
public class MathTask implements Task {

    private ClassRepresentatives representatives;

    public MathTask() {
        representatives = new ClassRepresentatives();
    }

    @Override
    public void checkTask() {
        representatives.checkMath();
    }
}

场景使用:

 Task math = new MathTask();
 Task chinese = new ChineseTask();
 HeadTeacher teacher = new HeadTeacher(math);
 teacher.checkTask();
 //切换执行命令
 teacher.setTask(chinese);
 teacher.checkTask();

应用场景:

  • 需要将请求调用者与请求接收者解耦时;
  • 命令类不确定性高时,如频繁添加命令,删除命令;
  • 对命令有额外要求时,如命令的撤销或者恢复。

优点:

  • 解耦。调用者与接收者没有任何依赖关系;
  • 拓展性高。非常容易地添加或删除命令;

缺点:

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

小结
个人认为命令模式所带来的最大优势并不是将请求者与接收者解耦,而是在设计解耦过程中带来的可操作性。使用命令模式可以很轻松地增加命令(虽然命令类多起来也会显得很重复累赘),以及添加其他的操作,例如撤销,恢复(可以结合备忘录模式)。如果没有使用命令模式设计代码,请求者直接调用接收者完成请求,这部分请求执行代码在多处使用就要多次创建,这会造成大量重复代码;当需要额外操作时往往是在接收者加以各种逻辑,接收者代码可能会变得非常复杂,既包含各种请求的执行又包括各种执行条件,直接影响代码可读性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值