行为模式之命令模式

1 概述
命令模式" title="命令模式">命令模式(Command Pattern),是将请求封装成一系列命令对象,以解耦请求发起者和请求接收者的一种行为模式。
2 命令模式
正常情况下,请求发送者和请求接收者是相互耦合的,发送者直接调用接收者相关的方法,直接交互。
用命令模式进行改造,将两者交互的媒介----命令单独抽离出来,使得发送者和接收者相互独立,只依赖于命令对象,提高了扩展性和可维护性。同时,通过命令模式,我们还能完成一些高级操作,如撤销命令,方法参数化,命令入队,批量命令等等。
3 案例
通过一个简单的例子加深对命令模式的理解。小时候我们都玩过遥控赛车,赛车可以根据遥控器的按钮,执行相应的动作。我们作为命令的发送者,其实并不直接跟赛车交互,而是通过遥控器的指令来操作赛车:
public interface RemoteControlCar { void moveForward();
void turnLeft();
void turnRight();
void moveBackward();
}
//请求接收者
public class RemoteControlCarImpl implements RemoteControlCar {
[@Override](https://my.oschina.net/u/1162528)
public void moveForward() {
System.out.println("The car is moving forward!");
}
[@Override](https://my.oschina.net/u/1162528)
public void turnLeft() {
System.out.println("The car turns left!");
}
[@Override](https://my.oschina.net/u/1162528)
public void turnRight() {
System.out.println("The car turns right!");
}
[@Override](https://my.oschina.net/u/1162528)
public void moveBackward() {
System.out.println("The car is moving backward!");
}
}
//命令接口,支持回退操作
public interface RemoteControlCommand {
void execute();
void undo();
}
public class ForwardCommand implements RemoteControlCommand {
RemoteControlCar rcCar;
public ForwardCommand(RemoteControlCar rcCar) {
this.rcCar = rcCar;
}
[@Override](https://my.oschina.net/u/1162528)
public void execute() {
rcCar.moveForward();
}
@Override
public void undo() {
rcCar.moveBackward();
}
}
public class BackwardCommand implements RemoteControlCommand {
RemoteControlCar rcCar;
public BackwardCommand(RemoteControlCar rcCar) {
this.rcCar = rcCar;
}
@Override
public void execute() {
rcCar.moveBackward();
}
@Override
public void undo() {
rcCar.moveForward();
}
}
public class TurnLeftCommand implements RemoteControlCommand {
RemoteControlCar rcCar;
public TurnLeftCommand(RemoteControlCar rcCar) {
this.rcCar = rcCar;
}
@Override
public void execute() {
rcCar.turnLeft();
}
@Override
public void undo() {
rcCar.turnRight();
}
}
public class TurnRightCommand implements RemoteControlCommand {
RemoteControlCar rcCar;
public TurnRightCommand(RemoteControlCar rcCar) {
this.rcCar = rcCar;
}
@Override
public void execute() {
rcCar.turnRight();
}
@Override
public void undo() {
rcCar.turnLeft();
}
}
public interface CarPlayer {
void play();
void undo();
void setCommand(RemoteControlCommand command);
}
// 命令发送者,将请求委托给命令对象来完成。通过设置不同的命令,完成不同的操作
public class Kid implements CarPlayer {
RemoteControlCommand command;
public Kid(RemoteControlCommand command) {
this.command = command;
}
@Override
public void setCommand(RemoteControlCommand command) {
this.command = command;
}
@Override
public void play() {
command.execute();
}
@Override
public void undo() {
command.undo();
}
}
public class Test {
public static void main(String[] args) {
RemoteControlCar remoteControlCar = new RemoteControlCarImpl();
RemoteControlCommand moveCommand = new ForwardCommand(remoteControlCar);
RemoteControlCommand turnLeftCommand = new TurnLeftCommand(remoteControlCar);
RemoteControlCommand turnRightCommand = new TurnRightCommand(remoteControlCar);
RemoteControlCommand stopCommand = new BackwardCommand(remoteControlCar);
// 需要完成不同的操作,只需设置不同的命令
CarPlayer kid = new Kid(moveCommand);
kid.play();
kid.undo();
kid.setCommand(turnLeftCommand);
kid.play();
kid.setCommand(turnRightCommand);
kid.play();
kid.setCommand(stopCommand);
kid.play();
kid.undo();
}
}
输出:
The car is moving forward!The car is moving backward!
The car turns left!
The car turns right!
The car is moving backward!
The car is moving forward!
在上述例子中,我们避免了CarPlayer和RemoteControlCar的直接交互,将所有的复杂度都放在RemoteControlCommand中。对命令的增删改并不影响整体系统。在这里只演示了通过命令模式可以完成撤销操作;不过很容易联想,将几个命令放到一个命令集合中一起调用,便可以达到批量操作的目的;将命令放入队列,用类似生产者--消费者的模式,可以做到延迟命令/命令入队的要求。
JDK中我们熟悉线程,就是命令模式的运用。Runnable相当于是Thread对象的命令。
4 总结
命令对象是命令模式的核心,它像是一个桥梁,连接了请求调用者和接收者,并解耦了两者的关系。它使得系统扩展变得容易。
文中例子的github地址
以上是 行为模式之命令模式 的全部内容, 来源链接: utcz.com/z/517084.html

