介绍:将一个请求封装成一个对象,从而使你可以用不同的请求对客户参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
场景:我们玩过很多游戏,现在需要我们设计一个2D飞行射击游戏,对于游戏有以下需求
角色 | 作用 |
---|---|
Receiver | 于接收请求,处理真正的业务逻辑 |
Command | 抽象命令类,定义命令方法 |
角色 | 作用 |
---|---|
ConcreteCommand | 具体命令类,实现Command方法 |
Invoker | 请求者,发起命令 |
接收者,我们需要实现具体对4种情况的实现
public class Receiver {
// 向左操作
public void left() {
System.out.println("to left");
}
// 向右
public void right() {
System.out.println("to right");
}
// 切换武器
public void transform() {
System.out.println("transform weapon");
}
// 射击
public void shot() {
System.out.println("shot biu biu biu");
}
}
命令者接口
public interface Command {
public void execute();
}
具体命令类:左按钮
public class LeftCommand implements Command {
private Receiver receiver;
public LeftCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.left();
}
}
具体命令类:右按钮
public class RightCommand implements Command {
private Receiver receiver;
public RightCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.right();
}
}
具体命令类:射击按钮
public class ShotCommand implements Command {
private Receiver receiver;
public ShotCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.shot();
}
}
具体命令类:转换按钮
public class TransformCommand implements Command {
private Receiver receiver;
public TransformCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.transform();
}
}
我们可以设置一个对象,将所有类型的命令封装起来,而客户端调用的就是请求者,只要直接执行对应方法就行。
请求者类:命令由按钮发起
public class Button {
private LeftCommand leftCommand;
private RightCommand rightCommand;
private ShotCommand shotCommand;
private TransformCommand transformCommand;
public void left() {
leftCommand.execute();
}
public void right() {
rightCommand.execute();
}
public void shot() {
shotCommand.execute();
}
public void transform() {
transformCommand.execute();
}
public void setLeftCommand(LeftCommand leftCommand) {
this.leftCommand = leftCommand;
}
public void setRightCommand(RightCommand rightCommand) {
this.rightCommand = rightCommand;
}
public void setShotCommand(ShotCommand shotCommand) {
this.shotCommand = shotCommand;
}
public void setTransformCommand(TransformCommand transformCommand) {
this.transformCommand = transformCommand;
}
}
我们可以用平时比较常用的键位来设定成本次使用的,如:w,s,a,d
玩家
// 最终接受者
Receiver receiver = new Receiver();
// 命令
LeftCommand leftCommand = new LeftCommand(receiver);
RightCommand rightCommand = new RightCommand(receiver);
ShotCommand shotCommand = new ShotCommand(receiver);
TransformCommand transformCommand = new TransformCommand(receiver);
// 设置按钮
Button button = new Button();button.setTransformCommand(transformCommand);
button.setLeftCommand(leftCommand);
button.setRightCommand(rightCommand);
button.setShotCommand(shotCommand);
Scanner scan = new Scanner(System.in);
while (true) {
String read = scan.nextLine();
switch (read) {
case "w":
button.shot();
break;
case "s":
button.transform();
break;
case "a":
button.right();
break;
case "d":
button.left();
break;
default:
break;
}
}
输出
w
shot biu biu biu
s
transform weaponato right
dto left
总结:命令模式很好的对系统中的类进行解耦,而且提供了更灵活的操控性和扩展性,但是也造成了类的膨胀,可能当类较多时难以维护。
提枪策马乘胜追击04-21 20:01
代码小兵92504-17 16:07
代码小兵98804-25 13:57
杨晶珍05-11 14:54