一、模式分析
命令模式需要有以下几个角色:
- Receiver,是原子操作的执行者;
- Command,是封装各种原子操作的命令;
- Invoker,是命令的发起者;
二、模式实例
首先我们来定义Receiver角色,它是原子命令的最终执行者。比如,我们声明一辆车,包含了车子启动和停止所需要的所有原子操作。
public interface Car {
void stepOnBrake();
void pressEngin();
void switchShift(String shift);
void releaseHandBrake();
void stepOnThrottle();
void pullHandBrake();
}
@Slf4j
public class WulingCar implements Car {
@Override
public void stepOnBrake() {
log.info("踩住刹车...");
}
@Override
public void pressEngin() {
log.info("按下启停按钮...");
}
@Override
public void switchShift(String shift) {
log.info("换到{}档位...",shift);
}
@Override
public void releaseHandBrake() {
log.info("松开手刹...");
}
@Override
public void stepOnThrottle() {
log.info("踩油门...");
}
@Override
public void pullHandBrake() {
log.info("拉手刹...");
}
}
然后我们定义Command角色,不同的Command固化了不同Receiver和不同原子操作的执行顺序。
public interface Command {
void execute();
}
@Slf4j
public class NoCommand implements Command {
@Override
public void execute() {
log.info("这是个空命令,什么也不执行...");
}
}
@Slf4j
public class StartCommand implements Command {
private Car myCar;
public StartCommand(Car myCar){
this.myCar = myCar;
}
@Override
public void execute() {
myCar.stepOnBrake();
myCar.pressEngin();
myCar.switchShift("D");
myCar.releaseHandBrake();
myCar.stepOnThrottle();
log.info("汽车一键启动完成!");
}
}
@Slf4j
public class StopCommand implements Command {
private Car myCar;
public StopCommand(Car myCar){
this.myCar = myCar;
}
@Override
public void execute() {
myCar.stepOnBrake();
myCar.pullHandBrake();
myCar.switchShift("P");
myCar.pressEngin();
log.info("汽车一键停止完成!");
}
}
最后,再定义Invoker角色,使用什么命令都由它决定。
@Slf4j
public class OneKeyTool {
private Command startCommand = new NoCommand();
private Command stopCommand = new NoCommand();
public OneKeyTool(Car myCar){
this.startCommand = new StartCommand(myCar);
this.stopCommand = new StopCommand(myCar);
}
public void oneKeyStartCar(){
this.startCommand.execute();
}
public void oneKeyStopCar(){
this.stopCommand.execute();
}
}
作为外部用户,只需要和Invoker打交道即可。
@Slf4j
public class Main {
public static void main(String[] args) {
Car 五菱宏光 = new WulingCar();
OneKeyTool modelX = new OneKeyTool(五菱宏光);
modelX.oneKeyStartCar();
log.info("行驶了1000公里...");
modelX.oneKeyStopCar();
}
}
踩住刹车...
按下启停按钮...
换到D档位...
松开手刹...
踩油门...
汽车一键启动完成!
行驶了1000公里...
踩住刹车...
拉手刹...
换到P档位...
按下启停按钮...
汽车一键停止完成!
三、模式总结
命令模式最大的特点就是解耦了Invoker角色和Receiver角色,所有的操作都由Command来定义和调用。Invoker只需要决定使用哪一个Command即可。
网友评论