Java设计模式:六、命令模式

命令模式

需求

假设现在有一个智能遥控器,用来控制房间的一些电子产品。数字键0-9分别有不同的动作。
假如数字1,用来打开客厅电灯,数字2关闭客厅电灯。数字3打开卧室电灯,数字4关闭卧室电灯。数字5打开电视,数字6关闭电视。如果有这样一个需求,如何实现会比较简单呢。

分析
上述简述包含两种不同的对象。一是遥控器,用来操作对应的电子装置,二是电子装置,被遥控器操控。 先来定义这些电子装置:

/**
 * 客厅电灯对象
 **/
public class LivingRoomLight{
    public void on(){//打开客厅电灯}
    public void off(){//关闭客厅电灯}
}

/**
 * 卧室电灯对象
 **/
public class BedRoomLight{
    public void on(){//打开卧室电灯}
    public void off(){//关闭卧室电灯}
}

/**
 * 电视对象
 **/
public class Television{
    public void on(){//打开电视}
    public void off(){//关闭电视}
}

/**
 * 遥控器
 **/
public class Telecontroller {
    private LivingRoomLight livingRoomLight = new LivingRoomLight();
    private BedRoomLight bedRoomLight = new BedRoomLight();
    private Television television = new Television();

    public void buttonWasPressed(String btn){
        if("btn1".equals(btn)){
            livingRoomLight.on();
        } else if("btn2".equals(btn)){
            livingRoomLight.off();
        } else if("btn3".equals(btn)){
            bedRoomLight.on();
        } else if("btn4".equals(btn)){
            bedRoomLight.off();
        } else if("btn5".equals(btn)){
            television.on();
        } else if("btn6".equals(btn)){
            television.off();
        }
    }

}

/**
 * 人,操作遥控器
 **/
public class TelecontrollerTest {
    Telecontroller telecontroller = new Telecontroller();
    telecontroller.buttonWasPressed("btn3");
}

这是简易的一个遥控器,可以看到,遥控器严重依赖了执行者对象,设计模式原则为:依赖抽象而不依赖实际。这样依赖了具体类,给后期的扩展维护,带来极大的不便。例如:现在要给按钮7和8进行编程,实现控制电扇的动作。除了要增加电扇对象之外,还需要修改遥控器buttonWasPressed()方法。这样做是没有一点弹性的。
正好有一个模式:命令模式,可以解决这个问题。

命令模式
命令模式,将请求单独封装为一个对象,使请求者与执行者完美的进行了解耦。

Created with Raphaël 2.1.0 Client Client Command Command Command Command Receiver Receiver 创建命令 依赖执行者: 依赖执行者

创建命令对象

/**
 * 命令抽象类
 **/
public class Command{
    void execute();
}

/**
 * 打开电灯命令
 **/
public class LivingRoomLightOnCommand implements Command{
    LivingRoomLight livingRoomLight;
    public LivingRoomLightOnCommand (LivingRoomLight livingRoomLight){
        this.livingRoomLight = livingRoomLight;
    }
    public void execute(){
        livingRoomLight.on();
    }
}

/**
 * 打开电视命令
 **/
public class TelevisionOnCommand implements Command{
    Television television;
    public TelevisionOnCommand (Television television){
        this.television= television;
    }
    public void execute(){
        television.on();
    }
}

/**
 * 遥控器
 **/
public class Telecontroller {
    Command[] commands = new Command[8];
    public void setCommands (int index, Command command){
        commands[index] = command;
    }

    public void buttonWasPressed(int index){
        commands[index].execute();
    }
}

public class TelecontrollerTest {
    public static void main(String[] args){
        Telecontroller telecontroller = new TeleController();
        telecontroller.setCommands(1, new Command(new LivingRoomLigntOnCommand(new LivingRoomLight())));
        telecontroller.execute();
    }
}

这样遥控器只依赖了抽象的命令对象,如果增加或者删除被执行对象,遥控器代码都不需要改变。更加富有弹性。
命令模式一般用于队列的执行等模块。目前暂时还没有用到过命令模式。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值