设计模式(六)--命令模式

基本概念
命令模式使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦。

在命令模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求,同时命令模式也支持可撤销的操作。

通俗易懂的理解:将军发布命令,士兵去执行。其中有几个角色:将军(命令发布者)、士兵(命令的具体执行者)、命令(连接将军和士兵)。

命令模式的原理类图:

  • Invoker:调用者角色;
  • Command:命令角色,需要执行的所有命令都在这里,可以是接口或抽象类;
  • Receiver:接收者角色,知道如何实施和执行一个请求相关的操
  • ConcreteCommand:将一个接受者对象与一个动作绑定,调用接收者相应的的操作,实现execute。

那么这里举一个例子,酒店常常会有这么一个过程

在这里插入图片描述
具体的角色图示如下:
在这里插入图片描述

那么我们可以将图中每个角色,每个方法给与角色
在这里插入图片描述

  • takerOrder就是传递命令的,在这里就是顾客将菜单传递给了女招待
  • 顾客就是Client,这个很容易想到
  • 订单就是command,因为command中包含所作所有命令,那么这里可以理解为厨师要做的所有的菜
  • orderUp就是excute方法,这里就是女招待调用orderUp方法,做command里面的菜,而做菜的细节则交给厨师,所以女招待就是调用者,厨师就是接收者
    下面用智能家居写代码示例:

Command角色

package com.lin.command;

public interface Command {

    // 执行
    void execute();
    // 撤销
    void undo();
}

在上面只是用了一个Command类,而这里写了两个实现,一个是关闭,一个是开启,为的是以后能够扩展命令,扩展了命令之后,当然,本身一个按钮也是一个对象,首要也是因为写的时候要写成一个对象,而扩展的时候命令可以扩展,但是后面可以明显看出,reciver不能扩展方法,所以如果reciver要扩展,那么需要另想办法。

package com.lin.command;

public class LightOffCommand implements Command{

    
LightReceiver lightReceiver = null;
    
    @Override
    public void execute() {
        lightReceiver.off();
    }

    @Override
    public void undo() {
        lightReceiver.on();
    }
    
    public LightOffCommand(LightReceiver lightReceiver) {
        this.lightReceiver = lightReceiver;
    }
}
package com.lin.command;

public class LightOnCommand implements Command{

    LightReceiver lightReceiver = null;
    
    @Override
    public void execute() {
        lightReceiver.on();
    }

    @Override
    public void undo() {
        lightReceiver.off();
    }
    
    public LightOnCommand(LightReceiver lightReceiver) {
        this.lightReceiver = lightReceiver;
    }

}

那么如果没有命令的时候我们可以去用if去判断他是否为空再去执行,但是这里可以用类似于状态模式的方法,用无状态类先赋值给每个按钮,然后他里面的执行方法可以什么都不写,反正调用了也相当于什么也没有调用,这样就省去了if代码,有利于扩展性。

package com.lin.command;

// 控执行,初始化每个按钮
public class NoCommand implements Command{

    @Override
    public void execute() {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void undo() {
        // TODO Auto-generated method stub
        
    }

}

这里就是接受命令的类了也就是厨师

package com.lin.command;

public class LightReceiver {

    public void on() {
        System.out.println("电灯打开了。");
    }
    
    public void off() {
        System.out.println("电灯关闭了。");
    }
}

这就是女招待,调用者,setCommand就是绑定的方法

package com.lin.command;

public class RemoteController {

    Command[] onCommands;
    Command[] offCommands;
    
    Command undoCommand;
    
    public RemoteController() {
        onCommands = new Command[5];
        offCommands = new Command[5];
        
        for (int i = 0; i < offCommands.length; i++) {
            onCommands[i] = new NoCommand();
            offCommands[i] = new NoCommand();
        }
    }

    public void setCommand(int no, Command onCommand, Command offCommand) {
        onCommands[no] = onCommand;
        offCommands[no] = offCommand;
    }
    // 按下开按钮
    public void onButtonWasPushed(int no) {
        onCommands[no].execute();
        undoCommand = onCommands[no];
    }
    // 按下关按钮    
    public void offButtonWasPushed(int no) {
        offCommands[no].execute();
        undoCommand = offCommands[no];
    }
    // 按下撤销按钮
    public void undoButtonWasPushed(int no) {
        undoCommand.undo();
    }
    
}
package com.lin.command;

public class Client {

    public static void main(String[] args) {
        
        LightReceiver lightReceiver = new LightReceiver();
        
        LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
        LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
        
        RemoteController remoteController = new RemoteController();
        
        remoteController.setCommand(0, lightOnCommand, lightOffCommand);
        
        System.out.println("=============按下开=============");
        remoteController.onButtonWasPushed(0);
        
        System.out.println("=============按下关=============");
        remoteController.offButtonWasPushed(0);
        
        System.out.println("=============按下撤销=============");
        remoteController.undoButtonWasPushed(0);
        
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值