一、简述

命令模式(Command Pattern),将一个请求封装为一个对象或者操作封装到一个对象中,从而使用户可用不同的请求把客户参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

命令模式_模式开发

UML图中

  • Client:客户端,也就是发出命令者
  • Invoker:执行者,该类的职责就是调用命令对象执行具体的请求,相关的方法我们称为行动方法
  • Command:命令,定义所有具体命令类的抽象接口
  • ConcreteCommand:具体命令,实现了Command接口,在execute()方法中调用Receiver相关的方法
  • Receiver:接收者,负责执行具体逻辑

整体来看,命令模式比较繁琐,执行一个指令的过程被分解成了好几部分,相对的复杂度也提升了;但是命令模式结构还是很清晰的。

二、实现

首先,我们需要一个接收者Receiver,来实现我们所传递的命令。

public class Receiver {
    public void action(){
        //具体命令操作
        System.out.println("清除所有记忆");
    }
}

这里接收者只执行这一个命令,复杂的情况们可以继承Receiver来实现不同的接收者处理不同的命令。

再是一个命令的接口Command和一个具体的Command实现类CleanMemoryCommand,很简单,只有一个没有实现的execute()方法。

/** 命令接口 */
public interface Command {
    public void execute();
}

/** 清除记忆命令 */
public class CleanMemoryCommand implements Command {

    Receiver receiver;

    public CleanMemoryCommand(Receiver receiver){
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.action();
    }
}

这样,命令和接收者都有了,我们只差一个供用户直接使用的Invoker了。

public class Invoker {

    private Command command;

    public Invoker(Command command){
        this.command = command;
    }

    public void actoin(){
        command.execute();
    }

}

调用的代码就比较简单了,这代码可以封装成一个方法

public class Client {
    public static void main(String[] args){
        Receiver receiver = new Receiver();
        CleanMemoryCommand command = new CleanMemoryCommand(receiver);
        Invoker invoker = new Invoker(command);
        invoker.actoin();
    }
}

三、总结

命令模式看似简单,细想来其实存在着几乎所有设计模式的通病,那就是大量衍生类的创建,这是一个不可避免的问题。

尽管如此,也给我们带来了许多好处,更弱的耦合性、更灵活的控制性以及更好的扩展性。但是最后还是那句话,用不用,还是根据实际情况而定。

——————————————————————————————————
作者:MrTrying
链接:https://www.jianshu.com/p/557441328d20
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。