设计模式--------命令模式
介绍命令模式的四大问题
- 现在的写法有什么问题吗?
- 为什么要用命令模式?
- 什么是命令模式?
- 命令模式有什么好处?
使用一个例子进行问题的说明
- 例如有一个开关遥控器,控制多个电器的开关,每个电器旁有二个按钮,分别控制开和关
Light
public class Light {
public void on() {
System.out.println("light on");
}
public void off() {
System.out.println("light off");
}
}
SimpleControl
public class SimpleControl {
Light light;
Tv tv;
public SimpleControl(Light light, Tv tv) {
this.light = light;
this.tv = tv;
}
public void lightOn() {
light.on();
}
public void lightOff() {
light.off();
}
public void tvOn() {
tv.on();
}
public void tvOff() {
tv.off();
}
}
有什么问题?
- 可以看的出每新增一个电器就会修改遥控器的代码,不符合开闭原则
- 而且遥控器和电器的耦合性紧
- 而且不符合针对接口编程
什么是命令模式?
- 将请求封装成对象,可以让你使用不同的请求,队列,或者日志请求来参数化其他对象,同时可以支持撤销操作
- 命令模式的分工
- 客户:命令模式将客户的请求封装成命令对象,告知客户将要请求什么(例如:我们手点击关按钮为一个关命令)
- 命令对象:命令对象中封装着调用者(灯)要执行的命令,并且其中存着调用者(灯)的实例(例如:关灯,开灯)
- 接受者:接受者(遥控器)收到命令,调用命令对象的执行方法(例如:遥控器)
- 调用者:调用者就是要干活的对象(例如:灯)
使用命令模式重构代码
Light
public class Light {
public void on() {
System.out.println("light on");
}
public void off() {
System.out.println("light off");
}
}
Command : 命令对象接口
public interface Command {
public void execute();
}
LightOnCommand: 开命令对象
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
LightOffCommand: 关命令对象
public class LightOffCommand implements Command {
Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
}
Control:调用者:遥控器
public class Control {
Command onCommand;
Command offCommand;
public void setCommand(Command onCommand, Command offCommand) {
this.onCommand = onCommand;
this.offCommand = offCommand;
}
public void buttonOnPress() {
onCommand.execute();
}
public void buttonOffPress() {
offCommand.execute();
}
}
Main
public class Main {
public static void main(String[] args) throws Exception {
Light light = new Light();
LightOnCommand onCommand = new LightOnCommand(light);
LightOffCommand offCommand = new LightOffCommand(light);
Control control = new Control();
control.setCommand(onCommand, offCommand);
control.buttonOnPress();
control.buttonOffPress();
}
}
命令模式有什么好处?
- 松耦合:将灯和遥控器分开了,通过一个命令对象进行交互
- 拓展性强:继承Command接口
- 同时可以再次基础上写撤回等功能
- 拓展Light的方法,加一个undo方法
- Control中记录上一次的命令对象,新增一个undo方法,当调用遥控器的undo方法时,回哦这上一次的命令对象,通过它其中的Light实例,调用Light的undo()方法
- 同时可以更加拓展写个堆栈,以无限的撤回
END
不慕招式,勤修内功