命令模式(行为型)

一:相关定义

命令模式:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。


二:相关类图和示例:

命令模式类图:


不结合示例来看的话,完全懵逼,主要看下面示例吧还是:

命令模式示例图:


看上面的示例图,虽然有一些注释,但我们在不了解前因后果的情况下,还是不懂它想表达什么,那就让我慢慢道来。

先说需求:有一个遥控器,它想要控制家里一堆电器的开关(例如:电灯,电视,音响,空调...),它有两列按钮,分别是on和off,每一对对应于一种电器的开和关,同时,最下面还有一个撤销按钮,用于撤销最后的一个操作;

怎么设计实现呢?第一反应,每个按钮绑定一个控制电器的事件。再想想,当然不行啦,因为我们可能会调整两对按钮控制不同电器的顺序,而且还会删除一个电器控制,新增一个电器控制,这样一来,就必然要求我们的遥控器(调用者)和控制具体电器的开关命令解耦和;如何解耦和呢?我们可以将这些控制开关的命令作为参数传递给遥控器,这样不就起到一个按钮就可以根据命令来控制所有开关的作用了吗,还是看代码吧,表达能力有限。

先来看这个遥控器(调用者):

public class RemoteControl{
    //使用数组记录一系列开与关的命令
    Command[] onCommand;
    Command[] offCommand;

    public RemoteControl{
        //7组按钮
        onCommand = new Command[7];
        offCommand = new Command[7];
        //实例化并初始化数组
        Command noCommand = new noCommand();
        for(int i = 0; i < 7; i++){
            onCommand[i] = noCommand;
            offCommand[i] = noCommand;
        }
    }

    //setCommand有3个参数,分别是插槽位置,开命令和关命令
    public void setCommand(int slot, Command onCommand, Command offCommand){
        onCommand[slot] = onCommand;
        offCommand[slot] = offCommand;
    }

    public void onButtonWasPushed(int slot){
        onCommand[slot].execute();
    }

    public void offButtonWasPushed(int slot){
        offCommand[slot].execute();
    }

    public String toString(){
        //打印每个插槽和对应的命令
    }
}

再来看我们使用的命令:

//Command命令接口定义了execute()方法,由遥控器调用
public class LightOffCommand implements Command{
    //厂商提供的电器类,其中有一系列控制这个电器的方法
    Light light;

    public LightOffCommand(Light light){
        this.light = light;
    }

    public void execute(){
        light.off();
    }
}

这个命令使得我们的遥控器(调用者)在不知道具体厂商类的情况下,就可以控制该厂商的电器开关。

来看看我们客户端如何使用的:

public class RemoteLoader{
    public static void main(String[] args){
        //调用者:遥控器
        RemoteControl remoteControl = new RemoteControl();

        //创建相应的命令对象(这里我们只创建一个,都是类似的)
        Light LivingRoomLight = new Light("Living Room");
        LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
        LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);

        //进行加载装配
        remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff);
        //进行测试调用
        remoteControl.onButtonWasPushed();
        remoteControl.offButtonWasPushed();
    }
}

到这里,我想大概你明白命令模式干嘛的了吧,剩下的操作还有撤销undo(),其实就是在命令接口Command中新增一个undo()方法,让具体命令去实现,遥控器每次按键时都将这个命令记录,撤销时调用命令的撤销方法。


参考书籍:《head first 设计模式》《大话设计模式》

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值