定义:将一个请求封装成一个对象,从而让你使用不一样的请求把客户端参数化,对请求排队或者记录请求日志,能够提供命令的撤销和恢复功能。 设计模式
类型:行为类模式 this
类图: spa
命令模式的结构 设计
顾名思义,命令模式就是对命令的封装,首先来看一下命令模式类图中的基本结构: 日志
以上三个类的做用应该是比较好理解的,下面咱们重点说一下Invoker类和Recevier类。 对象
所谓对命令的封装,说白了,无非就是把一系列的操做写到一个方法中,而后供客户端调用就好了,反映到类图上,只须要一个ConcreteCommand类和Client类就能够完成对命令的封装,即便再进一步,为了增长灵活性,能够再增长一个Command类进行适当地抽象,这个调用者和接收者究竟是什么做用呢? 开发
其实你们能够换一个角度去想:假如仅仅是简单地把一些操做封装起来做为一条命令供别人调用,怎么能称为一种模式呢?命令模式做为一种行为类模式,首先要作到低耦合,耦合度低了才能提升灵活性,而加入调用者和接收者两个角色的目的也正是为此。命令模式的通用代码以下: it
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
class
Invoker
{
private
Command
command
;
public
void
setCommand
(
Command
command
)
{
this
.
command
=
command
;
}
public
void
action
(
)
{
this
.
command
.
execute
(
)
;
}
}
abstract
class
Command
{
public
abstract
void
execute
(
)
;
}
class
ConcreteCommand
extends
Command
{
private
Receiver
receiver
;
public
ConcreteCommand
(
Receiver
receiver
)
{
this
.
receiver
=
receiver
;
}
public
void
execute
(
)
{
this
.
receiver
.
doSomething
(
)
;
}
}
class
Receiver
{
public
void
doSomething
(
)
{
System
.
out
.
println
(
"接受者-业务逻辑处理"
)
;
}
}
public
class
Client
{
public
static
void
main
(
String
[
]
args
)
{
Receiver
receiver
=
new
Receiver
(
)
;
Command
command
=
new
ConcreteCommand
(
receiver
)
;
//客户端直接执行具体命令方式(此方式与类图相符)
command
.
execute
(
)
;
//客户端经过调用者来执行命令
Invoker
invoker
=
new
Invoker
(
)
;
invoker
.
setCommand
(
command
)
;
invoker
.
action
(
)
;
}
}
|
经过代码咱们能够看到,当咱们调用时,执行的时序首先是调用者类,而后是命令类,最后是接收者类。也就是说一条命令的执行被分红了三步,它的耦合度要比把全部的操做都封装到一个类中要低的多,而这也正是命令模式的精髓所在:把命令的调用者与执行者分开,使双方没必要关心对方是如何操做的。 io
命令模式的优缺点 table
首先,命令模式的封装性很好:每一个命令都被封装起来,对于客户端来讲,须要什么功能就去调用相应的命令,而无需知道命令具体是怎么执行的。好比有一组文件操做的命令:新建文件、复制文件、删除文件。若是把这三个操做都封装成一个命令类,客户端只须要知道有这三个命令类便可,至于命令类中封装好的逻辑,客户端则无需知道。
其次,命令模式的扩展性很好,在命令模式中,在接收者类中通常会对操做进行最基本的封装,命令类则经过对这些基本的操做进行二次封装,当增长新命令的时候,对命令类的编写通常不是从零开始的,有大量的接收者类可供调用,也有大量的命令类可供调用,代码的复用性很好。好比,文件的操做中,咱们须要增长一个剪切文件的命令,则只须要把复制文件和删除文件这两个命令组合一下就好了,很是方便。
最后说一下命令模式的缺点,那就是命令若是不少,开发起来就要头疼了。特别是不少简单的命令,实现起来就几行代码的事,而使用命令模式的话,不用管命令多简单,都须要写一个命令类来封装。
命令模式的适用场景
对于大多数请求-响应模式的功能,比较适合使用命令模式,正如命令模式定义说的那样,命令模式对实现记录日志、撤销操做等功能比较方便。
总结
对于一个场合到底用不用模式,这对全部的开发人员来讲都是一个很纠结的问题。有时候,由于预见到需求上会发生的某些变化,为了系统的灵活性和可扩展性而使用了某种设计模式,但这个预见的需求恰恰没有,相反,没预见到的需求却是来了很多,致使在修改代码的时候,使用的设计模式反而起了相反的做用,以致于整个项目组怨声载道。这样的例子,我相信每一个程序设计者都遇到过。因此,基于敏捷开发的原则,咱们在设计程序的时候,若是按照目前的需求,不使用某种模式也能很好地解决,那么咱们就不要引入它,由于要引入一种设计模式并不困难,咱们大能够在真正须要用到的时候再对系统进行一下,引入这个设计模式。
拿命令模式来讲吧,咱们开发中,请求-响应模式的功能很是常见,通常来讲,咱们会把对请求的响应操做封装到一个方法中,这个封装的方法能够称之为命令,但不是命令模式。到底要不要把这种设计上升到模式的高度就要另行考虑了,由于,若是使用命令模式,就要引入调用者、接收者两个角色,本来放在一处的逻辑分散到了三个类中,设计时,必须考虑这样的代价是否值得。