首先请出今天的主人公——“人工智能”智能家电控制器
命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
现在我们做一个简单的控制器,假如它只有三个功能:显示使用物品名、开、关。
public interface Switch {
public void nameOfThing();//物品名称
public void on();//开
public void off();//关
}
两个可以实现功能的家电:电视、电灯。
public class TV implements Switch{//电视
@Override
public void nameOfThing() {
System.out.println("您正在操作电视");
}
@Override
public void on() {
System.out.println("电视显示画面");
}
@Override
public void off() {
System.out.println("电视画面消失");
}
}
public class lamp implements Switch {//电灯
@Override
public void nameOfThing() {
System.out.println("您正在操作灯");
}
@Override
public void on() {
System.out.println("灯亮");
}
@Override
public void off() {
System.out.println("灯灭");
}
}
那么设计到这就结束了?那就太过简单了,做一个合格的程序猿应该具备实现“解耦”,所以我们加入了“一键启动”和“一键关闭”两个方法
public class Switcher {
private Switch aSwitch;
public void setaSwitch(Switch aSwitch) {
this.aSwitch = aSwitch;
}
public void nameOut(){
aSwitch.nameOfThing();
}
public void buttonOnClick(){
System.out.println("点击【开】");
aSwitch.on();
}
public void buttonOffClick(){
System.out.println("点击【关】");
aSwitch.off();
}
}
在第三行中,我们引入了接口类,然后实现了名字显示、“一键启动”、“一键关闭”功能。
在客户使用时,就直接“傻瓜式”的操作即可
public class Client {//客户使用端
public static void main(String[] args) {
Switcher switcher = new Switcher();//创造一个可以使用的控制器
switcher.setaSwitch(new TV());//控制器上连接电视
switcher.nameOut();
switcher.buttonOnClick();
switcher.buttonOffClick();
switcher.setaSwitch(new lamp());//控制器连接电灯
switcher.nameOut();
switcher.buttonOnClick();
switcher.buttonOffClick();
}
}
让我们来运行一下
那么这个所谓的中央智能控制器就这么low吗?只能控制开关吗?
我们在控制开关的接口上来拓展功能,现在我们得新定义出一组”命令“接口把控制器(发令者)与设备(执行者)彻底解耦,我们在原有接口上拓展一个音量控制接口和一个温度控制接口。这样一来,你就会发现,如果一类家电都有同一功能,我们就可以用同一种方式来对物品控制,比如具有音量控制的电视、音响、收音机,有温度控制的空调、冰箱。
我们都知道家电如使用,就必须打开它,所以我们继承了开关接口,并保持了向后兼任性。
public interface TemperatureCommand extends Switch {//温度控制
public void temperatureUp();//温度增高
public void temperatureDown();//温度降低
}
public interface VolumeCommand extends Switch {//音量控制
public void volumeUp();//音量增高
public void volumeDown();//音量降低
}
我们具体一个事物:比如有温度控制的空调和有音量控制的电视
public class Air_conditioner implements TemperatureCommand {
@Override
public void nameOfThing() { System.out.println("您正在操作【空调】"); }
@Override
public void on() { System.out.println("空调开启"); }
@Override
public void off() { System.out.println("空调关闭"); }
@Override
public void temperatureUp() { System.out.println("空调温度增高【+】"); }
@Override
public void temperatureDown() { System.out.println("空调温度降低【-】"); }
}
public class TV implements VolumeCommand{
@Override
public void nameOfThing() { System.out.println("您正在操作【电视】"); }
@Override
public void on() { System.out.println("电视显示画面");}
@Override
public void off() { System.out.println("电视画面消失"); }
@Override
public void volumeUp() { System.out.println("电视音量增加【+】"); }
@Override
public void volumeDown() { System.out.println("电视音量减低【-】"); }
}
看过代码的你,是否发现如果我们都实现了这些功能,那我们的控制器上有几个按钮呢?至少8个!!!到这里,我们控制器外观设计师说了:“我们最好用一对控制键来完成一类功能”,所以我们只能由2个按钮,作为程序员的你一定要完成设计师和项目经理的任务!这是命令模式的关键
public interface Commend {
public void Up();//增加+
public void Down();//降低-
}
现在就ok了,只有两个了
public class Volume implements Commend {
private VolumeCommand volumeCommand;
public Volume(VolumeCommand volumeCommand) {
this.volumeCommand = volumeCommand;
}
@Override
public void Up() {
volumeCommand.volumeUp();
}
@Override
public void Down() {
volumeCommand.volumeDown();
}
}
public class Temperture implements Commend{
private TemperatureCommand temperatureCommand;//引入温度控制接口
public Temperture(TemperatureCommand temperatureCommand) {
this.temperatureCommand = temperatureCommand;
}
@Override
public void Up() {
temperatureCommand.temperatureUp();
}
@Override
public void Down() {
temperatureCommand.temperatureDown();
}
}
到这里,你会发现程序的复杂程序很大,所以需要耐心搞懂关系。然后我们做一个控制器
public class Controller {
private Commend commend;
public void setCommend(Commend commend) {
this.commend = commend;
}
public void buttonUpClick(){
System.out.println("按下【+】按钮");
commend.Up();
}
public void buttonDownClick(){
System.out.println("按下【-】按钮");
commend.Down();
}
}
对!它只有【+】和【-】
public class ImproveClient {
public static void main(String[] args) {
VolumeCommand tv = new TV();
TemperatureCommand air = new Air_conditioner();
Controller controller = new Controller();
//绑定命令和控制器
controller.setCommend(new Volume(tv));
controller.buttonUpClick();
controller.buttonDownClick();
controller.setCommend(new Temperture(air));
controller.buttonUpClick();
controller.buttonDownClick();
}
}
这是我们改进后的客户使用端,运行一下
这样的遥控器就可以使用与老人与小孩,大大提升了性能,这就是命令模式的魅力,虽然加大了程序的复杂程度,开发者需要有较强的逻辑思维,但作为程序员的你,这还不是小菜一碟!
发令控制方与接受执行方完全被拆解开,这样每个模块都可以自由的扩展胡维护,对指令映射、设备绑定的灵活操控,最终达到解耦的效果,这才是设计模式的精髓的所在啊。