博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
命令模式(Command)解析例子
阅读量:6160 次
发布时间:2019-06-21

本文共 3229 字,大约阅读时间需要 10 分钟。

本文深入浅出的讲述了设计模式中的命令模式
,
并给出了简单的示例
,
例子浅显易懂
,
并附带源代码。
      
命令模式属于行为模式。意图是将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求的排队或记录请求的日志,以及支持可以撤销的操作。又叫动作
(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)CommandlightOnOffCommand四个类,每个类都实现了Command接口,具备执行和撤销操作。
这些对象的协作关系是 Client创建一个具体的命令对象(fanOnCommand 并指定他的Receiverfan)对象,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
你可能感兴趣的文章
讲讲吸顶效果与react-sticky
查看>>
c++面向对象的一些问题1 0
查看>>
售前工程师的成长---一个老员工的经验之谈
查看>>
Get到的优秀博客网址
查看>>
老男孩教育每日一题-第107天-简述你对***的理解,常见的有哪几种?
查看>>
Python学习--time
查看>>
在OSCHINA上的第一篇博文,以后好好学习吧
查看>>
Spring常用注解
查看>>
linux:yum和apt-get的区别
查看>>
Sentinel 1.5.0 正式发布,引入 Reactive 支持
查看>>
数据库之MySQL
查看>>
2019/1/15 批量删除数据库相关数据
查看>>
数据类型的一些方法
查看>>
Webpack 2 中一些常见的优化措施
查看>>
移动端响应式
查看>>
js中var、let、const的区别
查看>>
简洁优雅地实现夜间模式
查看>>
react学习总结
查看>>
在soapui上踩过的坑
查看>>
MySQL的字符集和字符编码笔记
查看>>