由于最近一直在学习Golang,所以从本节起,所有设计模式学习笔记中的源码都由Golang来完成~
命令模式:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
仔细看这个定义,我们知道一个命令对象通过在特定接收者(receiver)上绑定一组动作来封装一个请求。要达到这一点,命令对象将动作和接收者包进对象中。这个对象只暴露出一个execute()方法,当此方法被调用的时候,接收者就会进行这些动作。从外面看,其他对象不知道究竟哪个接收者进行了哪些动作,只知道如果调用了execute(),请求的目的就达到了。这些就实现了接收者和调用者的解耦合。
实现命令接口:
首先让所有的命令对象实现相同的包含一个方法的接口:
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
|
type command
interface
{
execute()
}
//开灯命令
type lightOnCommand struct {
mLight *light
//命令对象包含的特定接收者
}
//返回一个开灯命令的实例对象
func NewLightOnCommand(light *light) command {
return
&lightOnCommand{mLight: light}
}
//实现接口方法捆绑接收者的动作
func (
this
*lightOnCommand) execute() {
if
!
this
.mLight.isOn() {
this
.mLight.setOn(
true
)
//开灯
}
}
//关灯命令
type lightOffCommand struct {
mLight *light
}
func NewLightOffCommand(light *light) command {
return
&lightOffCommand{mLight: light}
}
func (
this
*lightOffCommand) execute() {
if
this
.mLight.isOn() {
this
.mLight.setOn(
false
)
//关灯
}
}
|
我们应当考虑面向接口编程,大部分接收者都有简单的开关命令,故上述的代码可改为:
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
|
type receiver
interface
{
setOn(bool)
//true:开/false:关
isOn() bool
}
//打开命令
type onCommand struct {
receiver Receiver
}
//创建打开命令的实例,为该实例捆绑接收者
func NewOnCommand(receiver Receiver) command {
return
&onCommand{receiver}
}
//被封装的“请求”
func (
this
*onCommand) execute() {
if
!
this
.receiver.isOn() {
this
.receiver.setOn(
true
)
//打开
}
}
//关闭命令
type offCommand struct {
receiver Receiver
}
func NewOffCommand(receiver Receiver) command {
return
&offCommand{receiver}
}
func (
this
*offCommand) execute() {
if
!
this
.receiver.isOn() {
this
.receiver.setOn(
false
)
//关闭
}
}
|
最后,再来看看客户端的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
type RemoteController struct {
slot command
}
func (
this
*RemoteController) SetCommand(command command) {
this
.slot = command
}
func (
this
*RemoteController) ButtonPressed() {
if
this
.slot == nil {
panic(
"Do not assign command to Controller's slot!"
)
}
this
.slot.execute()
}
|
看看接收者们:
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
const
(
LIGHT =
" light"
DOOR =
" door"
)
//接收者接口
type Receiver
interface
{
setOn(bool)
isOn() bool
}
type light struct {
name string
on bool
}
func (
this
*light) setOn(b bool) {
if
b {
fmt.Println(
this
.name + LIGHT +
" is on."
)
}
else
{
fmt.Println(
this
.name + LIGHT +
" is off."
)
}
this
.on = b
}
func (
this
*light) isOn() bool {
return
this
.on
}
func NewRoomLight() Receiver {
return
&light{
"Room"
,
false
}
}
func NewTableLampLight() Receiver {
return
&light{
"Table Lamp"
,
false
}
}
type door struct {
name string
on bool
}
func (
this
*door) setOn(b bool) {
if
b {
fmt.Println(
this
.name + DOOR +
" is opened."
)
}
else
{
fmt.Println(
this
.name + DOOR +
" is closed."
)
}
this
.on = b
}
func (
this
*door) isOn() bool {
return
this
.on
}
func NewGarageDoor() Receiver {
return
&door{
"Garage"
,
false
}
}
func NewKitchenDoor() Receiver {
return
&door{
"Kitchen"
,
false
}
}
|
来测试下吧~:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
func main() {
ctrl :=
new
(command.RemoteController)
var roomLight, garageDoor command.Receiver
roomLight = command.NewRoomLight()
garageDoor = command.NewGarageDoor()
cmdOn := command.NewOnCommand(roomLight)
cmdOff := command.NewOffCommand(garageDoor)
ctrl.SetCommand(cmdOn)
ctrl.ButtonPressed()
ctrl.SetCommand(cmdOff)
ctrl.ButtonPressed()
}
|
本文转自 ponpon_ 51CTO博客,原文链接:http://blog.51cto.com/liuxp0827/1356520,如需转载请自行联系原作者