本文深入浅出的讲述了设计模式中的命令模式
,
并给出了简单的示例
,
例子浅显易懂
,
并附带源代码。
命令模式属于行为模式。意图是将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求的排队或记录请求的日志,以及支持可以撤销的操作。又叫动作
(Action)
或者事务
(Transaction)
。
有时必须向一个对象提交请求,但是并不知道关于被请求的操作或者请求的接受者的任何信息。命令模式通过将请求本身变成一个对象来使工具箱对象可向未指定的应用对象提出请求,这个对象可以被存储并像其他的对象一样被传递,这一个模式的关键是抽象的
Command
类,它定义了一个执行操作的接口,其最简单的形式是一个抽象的
Execute
操作,具体的
Command
子类将接收者作为其一个实例变量,并实现
Execute
操作
,
制定接收者采取的动作,而接收者有执行该请求所需的具体信息。
适用性:
l
抽象出待执行的动作以参数化某对象,适用过程语言中的回调函数表达这种参数化的机制。所谓的回调函数指函数先在某处注册,而他将在稍后的某个需要的时候被调用。
Command
模式是回调机制的一个面向对象的替代品。
l
在不同的时刻指定、排列和执行的请求。
l
支持取消操作
l
支持修改日志,这样当系统崩溃时这些修改可以被从新作一遍。
l
用构建在原语操作上的高层操作构造一个系统。这样一种结构支持事务的信息系统中很常见。
参与者:
Command
:声明执行操作的借口。
ConcreteCommand:
将一个接收者对象邦定于一个动作。
调用者收者相应的操作,以实现
Execute
。
Invoker(Dealer):
要求该命令执行这个请求。
Receiver(fan ,light)
:知道如何实施与执行一个请求相关的操作,任何类都可能是一个接收者。

图1
在这个例子中,被操作的对象有电风扇(fan)和灯(light),他们主要有开和关两种动作。把操作开或者关的请求封装成一个对象,于是就有了在本例中就有FanOn(Off)Command和lightOn(Off)Command四个类,每个类都实现了Command接口,具备执行和撤销操作。
这些对象的协作关系是 Client创建一个具体的命令对象(fanOnCommand) 并指定他的Receiver(fan)对象,Invoker(dealer)对象存储该具体的命令对象,该Invoker通过调用Command对象的Execute对象的Execute操作来提交一个请求,若该命令是可撤销的,具体的命令对象就再执行Execute之前存储当前的状态以取消该命令。具体对象调用它的Receiver对象的一些操作以执行该请求。
Command的代码:
package
command;
public
interface
Command{
public
void
execute();
public
void
unExecute();
}
Fan
的代码
package
command;
public
class
Fan{
private
String
state
;
public
Fan(){
state
=
"off"
;
}
public
void
startRotate(){
System.
out
.println(
"Fan is Being started !"
);
state
=
"on"
;
}
public
void
stopRotate(){
System.
out
.println(
"Fan has been stopped!"
);
state
=
"off"
;
}
public
String getState(){
return
state
;
}
}
FanOnCommand代码:
package
command;
public
class
FanOnCommand
implements
Command{
private
Fan
fan
;
private
boolean
change
;
public
FanOnCommand(Fan f){
change
=
false
;
fan
= f;
}
public
void
execute(){
if
(
"off"
.equals(
fan
.getState())){
change
=
true
;
fan
.startRotate();
}
else
{
change
=
false
;
System.
out
.println(
"The fan has been started! No Action!"
);
}
}
public
void
unExecute(){
if
(
change
){
fan
.stopRotate();
System.
out
.println(
" ==>from undo command!"
);
}
else
{
System.
out
.println(
"The Fan has been started! Undo nothing!"
);
}
}
}
Dealer代码:
package
command;
import
java.util.Vector;
public
class
Dealer{
private
Vector
v
;
public
Dealer(){
v
=
new
Vector();
}
public
void
deal(Command command){
v
.addElement(command);
command.execute();
}
public
boolean
unDeal(){
if
(
v
.size()>0){
Command command =(Command)
v
.get(
v
.size()-1);
command.unExecute();
v
.remove(
v
.size()-1);
return
true
;
}
else
{
return
false
;
}
}
}
Dealer
的代码:
package
command;
public
class
Client{
public
static
void
main(String[] args){
Fan fan =
new
Fan();
Light light =
new
Light();
Dealer dealer =
new
Dealer();
Command command =
new
LightOnCommand(light);
dealer.deal(command);
command =
new
FanOnCommand(fan);
dealer.deal(command);
command =
new
LightOnCommand(light);
dealer.deal(command);
command =
new
FanOnCommand(fan);
dealer.deal(command);
command =
new
LightOffCommand(light);
dealer.deal(command);
command =
new
FanOffCommand(fan);
dealer.deal(command);
while
(dealer.unDeal());
}
}
总结:命令模式有效的解决了操作中的撤销和重做动作的实现问题。桌面应用系统中的撤销和重做操作的实现是提高系统应用可信度的重要标志之一。
本文转自凌辉博客51CTO博客,原文链接http://blog.51cto.com/tianli/34197如需转载请自行联系原作者
lili00okok