1 需求
设计一个家电自动化遥控器的API
* 这个遥控器一共有7个可编程的插槽(每个都可以指定到一个不同的家电装置),每个插槽都有对应的开关按钮。这个遥控器还具备一个整体的撤销按钮。
* 有一组Java类,这些类是由多家厂商开发出来的,用来控制家电自动化装置,如电灯泡,风扇,热水器和音响等。
* 创建一组控制遥控器遥控的API,让每个插槽都能够控制一个或一组装置。注意:能够控制目前的装置和任何未来可能出现的装置,这一点很重要。
2 遥控器
3 厂商提供的类示例
如下
/*
电灯类
*/
public class Light {
public void on(){
System.out.println("电灯打开了");
}
public void off(){
System.out.println("电灯关闭了");
}
}
当然还有很多厂商类,许多类都具备on()和Off()方法,除此之外,还有像setVolumn()(设置音量)等方法
4 需求分析
* 遥控器应该知道如何解读按钮被按下的动作,然后发出正确的请求,但是遥控器不需知道这些家电自动化的细节,或者如何打开电灯,不然遥控器的代码将很复杂,而且需要大量的判断语句,这样的设计很糟糕,只要有新的厂商类进来,就必须修改代码,这样会造成潜在的错误,而且工作没完没了。
* 命令模式可将“动作的请求者”从“动作的执行者”对象中解藕。如请求者可以是遥控器,而执行者就是厂商类其中之一的实例。
* 利用命令对象,把请求(例如打开电灯)封装成一个特定对象(例如客厅电灯对象)。所以,如果每个按钮都存储一个命令对象,那么当按钮被按下的时候,就可以请命令对象做相关的工作。遥控器并不需要知道工作内容是什么,只要有个命令对象能和正确的对象沟通,把事情做好就可以了。遥控器和电灯对象就解藕了。
* 即创建一个API,将这些命令对象加载到按钮插槽,让遥控器的代码进来保持简单,而把家电自动化的工作(如开灯)和进行该工作的对象(如客厅的电灯)一起封装在命令对象中。
5 实现一个简单的遥控器开启电灯
public class Light {
public void on(){
System.out.println("电灯打开了");
}
}
/**
* @author hgl
* @data 2018年5月20日
* @description 命令接口 (示例一)
*/
public interface Command {
public void execute();
}
/**
* @author hgl
* @data 2018年5月20日
* @description 打开电灯命令,所以需要实现Command接口 (示例一)
*/
public class LightOnCommand implements Command {
public Light light;
/*
* 构造器被传入了某个电灯(比方说:客厅的电灯),以便让这个命令控制,然后记录在实例变量中。
* 一旦调用execute(),就由这个电灯对象成为接受者,负责接受请求。
*/
public LightOnCommand(Light light) {
super();
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
/**
* @author hgl
* @data 2018年5月20日
* @description 简单的遥控器,它只有一个按钮和对应的插槽,可以控制一个装置 (示例一)
*/
public class SimpleRemoteControl {
/*
* 有一个插槽持有命令,而这个命令控制一个装置
*/
public Command slot;
public SimpleRemoteControl(){
}
/*
* 这个方法用来设置插槽控制的命令。如果这段代码的客户想要改变遥控器按钮的行为,可以多次调用这个方法。
*/
public void setCommand(Command command){
slot =