设计模式command
命令(Command)设计模式是一种行为型设计模式,它将请求封装为对象,从而使你可以将请求的发起者和请求的接收者解耦。这样,你可以使用不同的请求、队列或日志来管理请求,还可以支持可撤销的操作。
假设我们有一个简单的遥控器,可以控制多个设备(例如灯和音响)。不使用命令模式时,代码可能会将所有控制逻辑硬编码在遥控器的类中,如下所示:
// 接收者类
class Light {
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}
class Stereo {
public void playMusic() {
System.out.println("Stereo is playing music");
}
public void stopMusic() {
System.out.println("Stereo stopped playing music");
}
}
// 遥控器类:所有控制逻辑都在这里
public class RemoteControl {
private Light light;
private Stereo stereo;
public RemoteControl(Light light, Stereo stereo) {
this.light = light;
this.stereo = stereo;
}
// 处理灯的操作
public void pressLightOnButton() {
light.turnOn();
}
public void pressLightOffButton() {
light.turnOff();
}
// 处理音响的操作
public void pressStereoPlayButton() {
stereo.playMusic();
}
public void pressStereoStopButton() {
stereo.stopMusic();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Light light = new Light();
Stereo stereo = new Stereo();
RemoteControl remote = new RemoteControl(light, stereo);
// 控制灯和音响
remote.pressLightOnButton(); // 输出: Light is ON
remote.pressStereoPlayButton(); // 输出: Stereo is playing music
remote.pressLightOffButton(); // 输出: Light is OFF
remote.pressStereoStopButton(); // 输出: Stereo stopped playing music
}
}
不使用命令模式的缺点
- 紧耦合:遥控器类直接依赖于具体的设备类(Light和Stereo)。如果要增加或修改设备(如增加一个风扇控制),必须修改遥控器的代码。
- 扩展性差:每新增一个设备或操作,都需要添加新的方法,导致遥控器类变得越来越复杂。
- 缺乏灵活性:遥控器的操作是硬编码的,不能轻易地将命令存储、撤销或动态改变行为。
- 难以维护:所有控制逻辑都集中在遥控器中,如果设备和操作增多,代码将变得难以维护。
使用命令模式的实现
使用命令模式,将操作封装成独立的命令类,让遥控器只需处理通用的命令接口。
// Command接口 interface Command { void execute(); } // 具体命令类:灯的开关 class LightOnCommand implements Command { private Light light; public LightOnCommand(Light light) { this.light = light; } @Override public void execute() { light.turnOn(); } } class LightOffCommand implements Command { private Light light; public LightOffCommand(Light light) { this.light = light; } @Override public void execute() { light.turnOff(); } } // 具体命令类:音响的播放和停止 class StereoPlayCommand implements Command { private Stereo stereo; public StereoPlayCommand(Stereo stereo) { this.stereo = stereo; } @Override public void execute() { stereo.playMusic(); } } class StereoStopCommand implements Command { private Stereo stereo; public StereoStopCommand(Stereo stereo) { this.stereo = stereo; } @Override public void execute() { stereo.stopMusic(); } } // 遥控器类:通过命令接口处理操作 class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { if (command != null) { command.execute(); } } } // 客户端代码 public class CommandPatternClient { public static void main(String[] args) { Light light = new Light(); Stereo stereo = new Stereo(); Command lightOn = new LightOnCommand(light); Command lightOff = new LightOffCommand(light); Command stereoPlay = new StereoPlayCommand(stereo); Command stereoStop = new StereoStopCommand(stereo); RemoteControl remote = new RemoteControl(); // 控制灯和音响 remote.setCommand(lightOn); remote.pressButton(); // 输出: Light is ON remote.setCommand(stereoPlay); remote.pressButton(); // 输出: Stereo is playing music remote.setCommand(lightOff); remote.pressButton(); // 输出: Light is OFF remote.setCommand(stereoStop); remote.pressButton(); // 输出: Stereo stopped playing music } }
- 解耦:遥控器不再直接依赖于具体的设备类,只需要处理命令接口,设备类可以独立变化。
- 扩展性强:新增设备或操作只需增加新的命令类,无需修改遥控器类。
- 灵活性:可以轻松地改变遥控器的行为,例如动态切换命令、实现撤销操作等。
- 易于维护:命令的实现被分散到各个独立的类中,职责清晰,易于维护和扩展。
浙公网安备 33010602011771号