您的位置:首页 > 编程语言 > Java开发

Java设计模式:命令模式(Command Pattern)

2017-08-15 16:31 801 查看
命令模式定义

命令模式将“请求”封装成对象,以便使用不同的请求、队列或日志来参数化其他对象。命令模式也支持可撤销的操作。

简易UML类图



1)Command 为所有命令声明了一个对象。调用命令对象的excute()方法就可以让接收者进行相关的动作。它也具备一个undo()方法,支持撤销。

2)客户端负责创建某一个具体的命令对象 ConcreteCommand,并设置其接收者Receiver

3)调用者Invoker 持有一个或多个Command命令对象,需设定,并在某个时间点调用  excute()方法

案例

UML类图



说明

1)该例只使用了两个设备 Light 和 CeilingFan 实例

2)Nocommand 对象是一个空对象。当你不想返回一个有意义的对象时,空对象就很有用。客户端也可以将处理null的责任转移给空对象。

3)MacroCommand 为 一键启动多功能,一键关闭多功能

代码

Command.java

public interface Command {
public void execute();
public void undo();
}
NoCommand.java

public class NoCommand implements Command {

public void execute() {
}

public void undo() {
}
}MacroCommand.java
public class MacroCommand implements Command {

Command[] commands;

public MacroCommand(Command[] commands){
this.commands = commands;
}

public void execute() {
// TODO Auto-generated method stub
for (int i = 0; i < commands.length; ++i){
commands[i].execute();
}
}

public void undo() {
// TODO Auto-generated method stub
for (int i = 0; i < commands.length; ++i){
commands[i].undo();
}
}

}

Light.java
public class Light {

String location;
int level;

public Light(String location) {
this.location = location;
}

public void on() {
level = 100;
System.out.println(location + "Light is on");
}

public void off() {
level = 0;
System.out.println(location + "Light is off");
}

public void dim(int level) {
this.level = level;
if (level == 0) {
off();
} else {
System.out.println("Light is dimmed to " + level + "%");
}
}

public int getLevel() {
return level;
}

}LightOffCommand.java
public class LightOffCommand implements Command {

Light light;

public LightOffCommand(Light light){
this.light = light;
}

public void execute() {
// TODO Auto-generated method stub
light.off();
}

public void undo() {
// TODO Auto-generated method stub
light.on();
}
}LightOnCommand.java
public class LightOnCommand implements Command {

Light light;

public LightOnCommand(Light light){
this.light = light;
}

public void execute() {
// TODO Auto-generated method stub
light.on();
}

public void undo() {
// TODO Auto-generated method stub
light.off();
}
}CeilingFan.java
public class CeilingFan {

String location = "";
int speed;

public static final int HIGH = 3;
public static final int MEDIUM = 2;
public static final int LOW = 1;
public static final int OFF = 0;

public CeilingFan(String location){
this.location = location;
speed = OFF;
}

public void high(){
speed = HIGH;
System.out.println(location + " ceiling fan is on high");
}

public void medium(){
speed = MEDIUM;
System.out.println(location + " ceililng fan is on medium");
}

public void low(){
speed = LOW;
System.out.println(location + " ceiling fan is on low");
}

public void off(){
speed = OFF;
System.out.println(location + " ceiling fan is on off");
}

public int getSpeed(){
return speed;
}
}CeilingFanHighCommand.java
public class CeilingFanHighCommand implements Command {

CeilingFan ceilingFan;
int prevSpeed;

public CeilingFanHighCommand(CeilingFan ceilingFan){
this.ceilingFan = ceilingFan;
}

public void execute() {
// TODO Auto-generated method stub
prevSpeed = ceilingFan.getSpeed();
ceilingFan.high();
}

public void undo() {
// TODO Auto-generated method stub
if (prevSpeed == CeilingFan.HIGH){
ceilingFan.high();
} else if (prevSpeed == CeilingFan.MEDIUM){
ceilingFan.medium();
} else if (prevSpeed == CeilingFan.LOW){
ceilingFan.low();
} else if (prevSpeed == CeilingFan.OFF){
ceilingFan.off();
}
}

}

CeilingFanMediumCommand.java
public class CeilingFanMediumCommand implements Command {

CeilingFan ceilingFan;
int prevSpeed;

public CeilingFanMediumCommand(CeilingFan ceilingFan){
this.ceilingFan = ceilingFan;
}

public void execute() {
// TODO Auto-generated method stub
prevSpeed = ceilingFan.getSpeed();
ceilingFan.medium();
}

public void undo() {
// TODO Auto-generated method stub
if (prevSpeed == CeilingFan.HIGH){
ceilingFan.high();
} else if (prevSpeed == CeilingFan.MEDIUM){
ceilingFan.medium();
} else if (prevSpeed == CeilingFan.LOW){
ceilingFan.low();
} else if (prevSpeed == CeilingFan.OFF){
ceilingFan.off();
}
}

}CeilingFanLowCommand.java
public class CeilingFanLowCommand implements Command {

CeilingFan ceilingFan;
int prevSpeed;

public CeilingFanLowCommand(CeilingFan ceilingFan){
this.ceilingFan = ceilingFan;
}

public void execute() {
// TODO Auto-generated method stub
prevSpeed = ceilingFan.getSpeed();
ceilingFan.low();
}

public void undo() {
// TODO Auto-generated method stub
if (prevSpeed == CeilingFan.HIGH){
ceilingFan.high();
} else if (prevSpeed == CeilingFan.MEDIUM){
ceilingFan.medium();
} else if (prevSpeed == CeilingFan.LOW){
ceilingFan.low();
} else if (prevSpeed == CeilingFan.OFF){
ceilingFan.off();
}
}

}

CeilingFanOffCommand.java
public class CeilingFanOffCommand implements Command {

CeilingFan ceilingFan;
int prevSpeed;

public CeilingFanOffCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
}

public void execute() {
// TODO Auto-generated method stub
prevSpeed = ceilingFan.getSpeed();
ceilingFan.off();
}

public void undo() {
// TODO Auto-generated method stub
if (prevSpeed == CeilingFan.HIGH) {
ceilingFan.high();
} else if (prevSpeed == CeilingFan.MEDIUM) {
ceilingFan.medium();
} else if (prevSpeed == CeilingFan.LOW) {
ceilingFan.low();
} else if (prevSpeed == CeilingFan.OFF) {
ceilingFan.off();
}
}
}RemoteControl.java
public class RemoteControl {

Command[] onCommands;
Command[] offCommands;
Command undoCommand; // 用于记录最后一个次执行的命令

public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7];

Command noCommand = new NoCommand();
for (int i = 0; i < 7; ++i) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = noCommand;
}

public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}

public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
}

public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
}

public void undoButtonWasPushed() {
undoCommand.undo();
}

public String toString() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("\n------------- Remote Control ----------\n");
for (int i = 0; i < onCommands.length; i++) {
stringBuffer.append("[slot " + i + "] "
+ onCommands[i].getClass().getName() + " "
+ offCommands[i].getClass().getName() + "\n");
}
return stringBuffer.toString();
}
}
Test.java
public class Test {

public static void main(String[] args) {
// TODO Auto-generated method stub

RemoteControl remoteControl = new RemoteControl();

System.out.println("*************测试灯********************");

Light livingRoomLight = new Light("Living Room");
LightOnCommand livingroomLightOn = new LightOnCommand(livingRoomLight);
LightOffCommand livingroomLightOff = new LightOffCommand(livingRoomLight);

remoteControl.setCommand(0, livingroomLightOn, livingroomLightOff);

remoteControl.onButtonWasPushed(0);
remoteControl.offButtonWasPushed(0);
System.out.println(remoteControl);

remoteControl.undoButtonWasPushed();
remoteControl.offButtonWasPushed(0);
remoteControl.onButtonWasPushed(0);
System.out.println(remoteControl);
remoteControl.undoButtonWasPushed();

System.out.println("*************测试吊扇********************");

CeilingFan ceilingFan = new CeilingFan("Living Room");

CeilingFanMediumCommand ceilingFanMedium = new CeilingFanMediumCommand(ceilingFan);
CeilingFanHighCommand ceilingFanHigh = new CeilingFanHighCommand(ceilingFan);
CeilingFanOffCommand ceilingFanOff = new CeilingFanOffCommand(ceilingFan);

remoteControl.setCommand(0, ceilingFanMedium, ceilingFanOff);
remoteControl.setCommand(1, ceilingFanHigh, ceilingFanOff);

remoteControl.onButtonWasPushed(0);
remoteControl.offButtonWasPushed(0);
System.out.println(remoteControl);
remoteControl.undoButtonWasPushed();

remoteControl.onButtonWasPushed(1);
System.out.println(remoteControl);
remoteControl.undoButtonWasPushed();

System.out.println("*************测试一键启动多种功能********************");
Command[] macroOn = {livingroomLightOn, ceilingFanMedium};
Command[] macroOff = {livingroomLightOff, ceilingFanOff};

MacroCommand onekeyOnMarco = new MacroCommand(macroOn);
MacroCommand onekeyOffMarco = new MacroCommand(macroOff);

remoteControl.setCommand(2, onekeyOnMarco, onekeyOffMarco);

System.out.println(remoteControl);
System.out.println("*************一键功能启动********************");
remoteControl.onButtonWasPushed(2);
System.out.println("*************一键功能关闭********************");
remoteControl.offButtonWasPushed(2);
}
}输出
*************测试灯********************
Living RoomLight is on
Living RoomLight is off

------------- Remote Control ----------
[slot 0] com.jing.command.remote.LightOnCommand com.jing.command.remote.LightOffCommand
[slot 1] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 2] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 3] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 4] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 5] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 6] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand

Living RoomLight is on
Living RoomLight is off
Living RoomLight is on

------------- Remote Control ----------
[slot 0] com.jing.command.remote.LightOnCommand com.jing.command.remote.LightOffCommand
[slot 1] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 2] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 3] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 4] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 5] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 6] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand

Living RoomLight is off
*************测试吊扇********************
Living Room ceililng fan is on medium
Living Room ceiling fan is on off

------------- Remote Control ----------
[slot 0] com.jing.command.remote.CeilingFanMediumCommand com.jing.command.remote.CeilingFanOffCommand
[slot 1] com.jing.command.remote.CeilingFanHighCommand com.jing.command.remote.CeilingFanOffCommand
[slot 2] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 3] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 4] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 5] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 6] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand

Living Room ceililng fan is on medium
Living Room ceiling fan is on high

------------- Remote Control ----------
[slot 0] com.jing.command.remote.CeilingFanMediumCommand com.jing.command.remote.CeilingFanOffCommand
[slot 1] com.jing.command.remote.CeilingFanHighCommand com.jing.command.remote.CeilingFanOffCommand
[slot 2] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 3] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 4] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 5] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 6] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand

Living Room ceililng fan is on medium
*************测试一键启动多种功能********************

------------- Remote Control ----------
[slot 0] com.jing.command.remote.CeilingFanMediumCommand com.jing.command.remote.CeilingFanOffCommand
[slot 1] com.jing.command.remote.CeilingFanHighCommand com.jing.command.remote.CeilingFanOffCommand
[slot 2] com.jing.command.remote.MacroCommand com.jing.command.remote.MacroCommand
[slot 3] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 4] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 5] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand
[slot 6] com.jing.command.remote.NoCommand com.jing.command.remote.NoCommand

*************一键功能启动********************
Living RoomLight is on
Living Room ceililng fan is on medium
*************一键功能关闭********************
Living RoomLight is off
Living Room ceiling fan is on off
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: