一、命令模式
命令模式将请求、命令、动作等封装成对象,这样可以让项目使用这些对象来
参数化其他对象。使得命令的请求者和执行者解耦
二、示例
家电自动化遥控器API项目:智能遥控器上有多个开关按钮,可是实现不同家电的控制,也可对新家电进行接入拓展
如果用传统面向对象的模式,则是定义一个遥控的对象,在对象内进行每个按钮的监听,分别判断进行相应的处理
1.电灯对象,控制开关
/**
* 电灯对象
*/
public class Light {
String loc = "";
public Light(String loc) {
this.loc = loc;
}
public void On() {
System.out.println(loc + " On");
}
public void Off() {
System.out.println(loc + " Off");
}
}
2.收音机对象,控制开关和音量
/**
* 收音机对象
*/
public class Stereo {
static int volume = 0;
public void On() {
System.out.println("Stereo On");
}
public void Off() {
System.out.println("Stereo Off");
}
public void SetCd() {
System.out.println("Stereo SetCd");
}
public void SetVol(int vol) {
volume = vol;
System.out.println("Stereo volume=" + volume);
}
public int GetVol() {
return volume;
}
public void Start() {
System.out.println("Stereo Start");
}
}
3.遥控器对象,进行判断处理
/**
* 面向对象模式,遥控对象根据按钮的序号进行相应的处理
*/
public class TraditionControl implements Control {
Light light;
Stereo stereo;
public TraditionControl(Light light, Stereo stereo) {
this.light = light;
this.stereo = stereo;
}
@Override
public void onButton(int slot) {
// TODO Auto-generated method stub
switch (slot) {
case 0:
light.On();
break;
case 1:
stereo.On();
break;
case 2:
int vol = stereo.GetVol();
if (vol < 11) {
stereo.SetVol(++vol);
}
break;
}
}
@Override
public void offButton(int slot) {
// TODO Auto-generated method stub
switch (slot) {
case 0:
light.Off();
break;
case 1:
stereo.Off();
break;
case 2:
int vol = stereo.GetVol();
if (vol > 0) {
stereo.SetVol(--vol);
}
break;
}
}
@Override
public void undoButton() {
// TODO Auto-generated method stub
}
}
缺点:所有操作均在遥控对象内控制,耦合度太高,且如果新增或删减电器则会对整个控制对象进行改动,不利于维护
三、命令模式的实现
1.定义统一的命令方法接口
/**
* 命令模式,命令方法接口
*/
public interface Command {
public void execute();
public void undo();
}
2.创建各自不同的命令对象
/**
* 命令模式,电灯打开的命令操作
*/
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.On();
}
@Override
public void undo() {
light.Off();
}
}
/**
* 命令模式,电灯关闭的命令操作
*/
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light)
{
this.light=light;
}
@Override
public void execute() {
light.Off();
}
@Override
public void undo() {
light.On();
}
}
3.遥控器对象对各命令进行抽象处理
/**
* 命令模式,所有响应均可抽象成命令,调用时直接调用命令执行方法即可
*/
public class CommandModeControl implements Control {
private Command[] onCommands;
private Command[] offCommands;
public CommandModeControl() {
onCommands = new Command[5];
offCommands = new Command[5];
Command noCommand = new NoCommand();
for (int i = 0, len = onCommands.length; i < len; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
}
public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
// 开
@Override
public void onButton(int slot) {
onCommands[slot].execute();
}
// 关
@Override
public void offButton(int slot) {
offCommands[slot].execute();
}
// 返回
@Override
public void undoButton() {
}
}
4.新增和删减电器时传入相应的实体类进行命令的初始化
/**
* 命令模式,便于拓展
*/
public class ControlTest {
public static void main(String[] args) {
CommandModeControl control = new CommandModeControl();
Light bedroomlight = new Light("BedRoom");
Light kitchlight = new Light("Kitch");
Stereo stereo = new Stereo();
LightOnCommand bedroomlighton = new LightOnCommand(bedroomlight);
LightOffCommand bedroomlightoff = new LightOffCommand(bedroomlight);
LightOnCommand kitchlighton = new LightOnCommand(kitchlight);
LightOffCommand kitchlightoff = new LightOffCommand(kitchlight);
StereoOnCommand stereoOn = new StereoOnCommand(stereo);
StereoOffCommand stereoOff = new StereoOffCommand(stereo);
StereoAddVolCommand stereoaddvol = new StereoAddVolCommand(stereo);
StereoSubVolCommand stereosubvol = new StereoSubVolCommand(stereo);
control.setCommand(0, bedroomlighton, bedroomlightoff);
control.setCommand(1, kitchlighton, kitchlightoff);
control.setCommand(2, stereoOn, stereoOff);
control.setCommand(3, stereoaddvol, stereosubvol);
control.onButton(0);
control.offButton(0);
control.onButton(1);
control.offButton(1);
control.onButton(2);
control.onButton(3);
control.offButton(3);
control.offButton(2);
}
}
优点:
- 命令之间相互分离,互不影响,也便于新命令的接入和删除。
- 即使新增返回按钮,和组合按钮等功能,也易于拓展且不影响其它命令。
Java设计模式所有示例代码,持续更新中
网友评论