一天一个设计模式---命令模式

介绍:将一个请求封装成一个对象,从而使你可以用不同的请求对客户参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

场景:我们玩过很多游戏,现在需要我们设计一个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 weapon
a
to right
d
to left

总结:命令模式很好的对系统中的类进行解耦,而且提供了更灵活的操控性和扩展性,但是也造成了类的膨胀,可能当类较多时难以维护。


更多模式:一天一个设计模式—分类与六大原则

更多源码: https://github.com/oDevilo/Java-Base

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值