关闭

命令模式(行为型)

标签: 设计模式
83人阅读 评论(0) 收藏 举报
分类:

  在古代两国交战,皇帝都不直接指挥军队,而是将指挥权交给得力大将,由他来指挥军队,将军如何指挥军队皇帝也不管,皇帝只要你打赢了就可以;当皇帝说不打了,就给将军发一道圣旨说撤退,怎么撤退皇帝也不管,由将军自由发挥。
  电视遥控器不会直接让电视换频道,是发出一个换频道信号,电视接收到了这个信号就执行换频道的操作。这个例子中遥控器是请求的发送者,电视机就是请求的接收者。
  在软件设计中,我们经常需要向某些对象发送请求,不过不知道请求的接收者是谁,也不知道被请求的操作是哪个,只要在程序运行时指定具体的请求接收者即可。这时使用命令模式,可以使发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,不必知道如何完成请求。
定义:将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
结构

  • 命令角色,定义命令的接口,声明具体命令类需要执行的方法
  • 具体命令角色:命令接口的实现,持有接收者,并调用接收者的功能来完成命令要执行的操作
  • 发送者角色:负责调用命令对象执行请求,持有命令对象;使用命令对象的入口
  • 接收者角色:真正的执行命令的对象。任何类都有可能成为一个接收者,只要它能够实现命令要求实现的相应功能。

适用场景

  • 系统需要将请求调用者和请求接收着解耦,使得调用者和接收者不直接交互
  • 系统需要在不同的时间指定请求、将请求排队和执行请求
  • 系统需要支持命令的撤销操作和回复操作
  • 系统需要将一组操作组合在一起

UML类图
这里写图片描述

下面是代码的实现:
Command

public interface Command {
    void execute1();
    void execute2();
}

public class ConcreteCommand implements Command {
    Receiver receiver;
    public ConcreteCommand(Receiver receiver){
        this.receiver = receiver;
    }
    @Override
    public void execute1() {
        receiver.executeAction1();
    }
    @Override
    public void execute2() {
        receiver.executeAction2();
    }
}

Invoker

public class Invoker {
    Command command;
    public void setCommand(Command command){
        this.command = command;
    }
    public void invoke(int i){
        if(i==1)
            command.execute1();
        if(i==2)
            command.execute2();
    }
}

Receiver

public class Receiver {
    public Receiver(){}
    public void executeAction1(){
        System.out.println("执行操作1");
    }
    public void executeAction2(){
        System.out.println("执行操作2");
    }
}

Test

public class Test {
    public static void main(String[] args){
        Receiver receiver = new Receiver();
        ConcreteCommand concreteCommand = new ConcreteCommand(receiver);
        Invoker invoker = new Invoker();
        invoker.setCommand(concreteCommand);
        invoker.invoke(2);
    }
}

总结
  命令模式很好地将降低了系统的耦合性,把命令的调用者与执行者分开,使双方不必关心对方是如何操作的,这是命令模式的精髓所在;也使得系统具有很好的扩展性,当有新的命令时,可以很容易的加入到系统中。
  但命令模式也时有缺点的,因为对于每一个命令都要有一个具体的类来实现,这样对于某些命令类型很多的系统来说,就会有很多的具体命令类,并且使用命令模式就要引入调用者接收者两个角色,势必增加类的数量,所有并不是使用了命令模式就是好的,需要做出权衡。


参考:https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/command/lijunhuayc
   http://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/command.html
   http://blog.csdn.net/zhengzhb/article/details/7550895

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2531次
    • 积分:245
    • 等级:
    • 排名:千里之外
    • 原创:23篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    文章分类
    文章存档
    最新评论