Java设计模式之命令模式

简介:

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

通常一个命令对象就是要执行的一个命令操作,实现了共同的接口,一个命令对象通过在特定的接受者上绑定一组动作来封装一个请求。一般命令对象将所要操作的动作和接受者绑定在里面,通过提供给外部一个execute()方法来触发所需要的操作。
命令模式实现了“命令的调用者”和“命令的接受者”之间的解耦,由于命令对象里面已经绑定了所要操作的接受者以及动作,而调用者只管负责调用相应的命令对象来完成命令所包含的动作,调用者根本不知道它所操作的是哪一个接受者,只知道它要做的是何种操作而已。
其实命令模式如同其他设计模式一样——通过将你的的请求和你的处理之间,加上了一个中间人的角色,来达到分离耦合的目的。通过对中间人角色的特殊设计来形成不同的模式。当然命令模式就是一种特殊设计的结果。
它的类图如下:
命令模式类图
通常它的组成包括如下:
1) 命令角色(Command):声明执行操作的接口。由接口或者抽象类来实现。
2) 具体命令角色(Concrete Command):将一个接收者对象绑定于一个动作,调用接收者相应的操作,以实现命令角色声明的执行操作的接口。
3) 客户角色(Client):创建一个具体命令对象(并可以设定它的接收者)。
4) 调用者角色(Invoker):调用命令对象执行这个请求。
5) 接收者角色(Receiver):知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。
一般来说具体命令角色仅仅包含着一种命令,如果想要一个命令包含多种命令那么就可以利用宏命令,在一个具体命令角色中提前设置好各种具体命令角色来处理。
命令模式一般具有撤销操作,一般就是在调用者里面做好预处理,在每一个具体命令角色设置好撤销操作的执行动作
命令模式的优点:
1) 命令模式将调用操作的请求对象与执行该操作的接收对象解耦。
2) 具体命令角色可以被不同的请求者角色重用。
3) 可将多个命令装配成一个复合命令,即宏命令。
4) 增加新的具体命令角色很容易,因为这无需改变已有的类。
命令模式的应用场景:
1) 需要抽象出待执行的动作,然后以参数的形式提供出来——类似于过程设计中的回调机制。而命令模式正是回调机制的一个面向对象的替代品。
2) 在不同的时刻指定、排列和执行请求。
3) 需要支持取消操作。
4) 支持修改日志功能。这样当系统崩溃时,这些修改可以被重做一遍。
5) 需要支持事务操作。
命令模式的要点:
1)在被解耦的两者之间即接受者和调用者通过命令对象来沟通的。
2)调用者通过调用命令对象的execute()发出请求,这就会促使接受者开始执行命令的动作。
举例说明:
一个控制器,可以控制许多个设备,通过向设备发出各种命令来执行。
命令角色接口:
package com.whut.command;
//各种命令的基类
public interface Command {
void execute();
void undo();
}
具体命令角色:
package com.whut.command;
public class LightOffCommand  implements Command {
Light light;
public LightOffCommand(Light light)
{
this.light=light;
}

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

@Override
public void undo() {
// TODO Auto-generated method stub
light.on();
}
}
调用者角色:
package com.whut.command;

public class RemoteControl {

private Command[] onCommands;
private Command[] offCommands;
private Command undoCommand;

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

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

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

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

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

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

@Override
public String toString()
{
StringBuffer stringBuff= new StringBuffer();
stringBuff.append( "\n------Remote Control-------------\n");
for( int i=0;i<7;i++)
{
stringBuff.append( "[slot "+i+ " ]"+onCommands[i].getClass().getName()
+ " "+offCommands[i].getClass().getName()+ "\n");
}
return stringBuff.toString();
}
}
接受者角色:
package com.whut.command;
//各种接受者
public class Light {

private String lightType;

public Light(String light)
{
this.lightType=light;
}
public void on()
{
System.out.println( "The "+lightType+ " is on...");
}

public void off()
{
System.out.println( "The "+lightType+ " is off...");
}
}
客户角色:
package com.whut.command;
public class RemoteLoader {
public static void main(String[] args)
{
RemoteControl remote= new RemoteControl();

Light livingRoomLight= new Light( "Living Room");
LightOnCommand livingRoomOn= new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomOff= new LightOffCommand(livingRoomLight);
remote.setCommand(0, livingRoomOn, livingRoomOff);

remote.onButtonWasPressed(0);
remote.offButtonWasPressed(0);
System.out.println(remote);
remote.undoButtonWasPressed();
remote.offButtonWasPressed(0);
remote.onButtonWasPressed(0);
System.out.println(remote);
}
}


本文转自 zhao_xiao_long 51CTO博客,原文链接:http://blog.51cto.com/computerdragon/1156583

相关文章
|
2天前
|
存储 设计模式 安全
Java设计模式-备忘录模式(23)
Java设计模式-备忘录模式(23)
|
2天前
|
设计模式 存储 算法
Java设计模式-命令模式(16)
Java设计模式-命令模式(16)
|
2天前
|
设计模式 Java
Java设计模式-装饰器模式(10)
Java设计模式-装饰器模式(10)
|
2天前
|
设计模式 Java 程序员
Java设计模式-适配器模式(8)
Java设计模式-适配器模式(8)
|
2天前
|
设计模式 存储 缓存
Java设计模式 - 解释器模式(24)
Java设计模式 - 解释器模式(24)
|
2天前
|
设计模式 安全 Java
Java设计模式-迭代器模式(21)
Java设计模式-迭代器模式(21)
|
2天前
|
设计模式 缓存 监控
Java设计模式-责任链模式(17)
Java设计模式-责任链模式(17)
|
2天前
|
设计模式 运维 算法
Java设计模式-策略模式(15)
Java设计模式-策略模式(15)
|
2天前
|
设计模式 算法 Java
Java设计模式-模板方法模式(14)
Java设计模式-模板方法模式(14)
|
2天前
|
设计模式 存储 安全
Java设计模式-组合模式(13)
Java设计模式-组合模式(13)