定义
命令模式(Command Pattern)又叫动作模式或事务模式。指的是将一个请求封装成一个对象,使发出请求的责任和执行请求的责任分割开,然后可以使用不同的请求把客户端参数化,这样可以使得两者之间通过命令对象进行沟通,从而方便将命令对象进行储存、传递、调用、增加与管理。命令模式是一种对象行为型模式。
命令模式就是对命令的封装,就是把一系列的操作写到一个方法中,然后供客户端调用就行了。主要的作用就是对请求发送者与接收者进行耦合,发送者与接收者之间没有直接引用关系,使得对象之间的调用关系更加灵活,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。
组成部分
命令模式主要由以下几个部分组成:
1、抽象命令类(Command):命令的抽象类,类中对需要执行的命令进行声明,一般来说要对外公布一个execute方法用来执行命令。
2、具体命令类(Concrete Command):抽象命令类的具体实现子类,对抽象类中声明的方法进行实现。
3、调用类(Invoker):调用者,负责调用命令,执行命令功能的相关操作,是具体命令对象业务的真正实现者。
4、接受类(Receiver):接收者,负责接收命令并且执行命令,是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。
例子
抽象命令类:
public abstract class Command { public abstract void execute(); } 复制代码
具体命令子类:
public class ConcreteCommand extends Command{ private Receiver receiver; public ConcreteCommand(){ this.receiver = new Receiver(); } @Override public void execute() { receiver.doSomething(); } } 复制代码
调用者:
public class Invoker { private Command command; public Invoker(Command command) { this.command = command; } public void setCommand(Command command) { this.command = command; } public void dosomething() { System.out.println("这里是调用者,执行命令"); command.execute(); } } 复制代码
接受者:
public class Receiver { public void doSomething(){ System.out.println("这是接受者负责处理业务逻辑"); } } 复制代码
测试方法:
public class CommandPatternTest { public static void main(String[] args){ Command command = new ConcreteCommand(); //客户端通过调用者来执行命令 Invoker invoker = new Invoker(command); System.out.println("客户端请求调用者"); invoker.dosomething(); } } 复制代码
运行结果:
可以发现上面代码执行的顺序是调用者,命令类,接收者类,也就是将一个请求的执行被分成了三步,把命令的调用者与执行者分开,使双方不必关心对方是如何操作的,从而降低了耦合度。
命令模式的优点
1、命令模式将命令都封装起来,所以封装性好;
2、命令模式将命令的调用者和执行者分开,使得双方不必知道对方是如何操作的,降低了耦合度;
3、命令模式的拓展性好,接受者会对操作进行基本的封装,命令类再对基本操作进行二次封装,增加新命令时不必从新写,代码的复用性好。
命令模式的缺点
一般如果拓展性好的同时会带来显著的缺点就是复杂,代码多,会有大量具体的命令类。命令模式同样的,如果命令很多的话,代码量就比较多。使用命令模式,不用管命令多简单,都需要写一个命令类来封装。
应用场景
1、对于很多数的请求-响应模式的功能,比较适合使用命令模式,命令模式对实现记录日志、撤销操作等功能比较方便。
2、命令模式可以使调用者和接收者不直接交互,对调用者和接收者进行解耦时,
总结
命令模式就是对命令的封装,就是把一系列的操作写到一个方法中,然后供客户端调用就行了。主要的作用就是对请求发送者与接收者进行解耦,发送者与接收者之间没有直接引用关系,使得对象之间的调用关系更加灵活,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。
至此所有的设计模式不知不觉都已经学习完了,本文以及之前的所有的设计模式中的例子代码,都将同步至github,需要的欢迎下载star。有任何问题欢迎一起交流、讨论!