1.智能生活項目需求
看一個具體的需求

我們買了一套智能家電,有照明燈、風扇、冰箱、洗衣機,我們只要在手機上安裝 app 就可以控制對這些家電工作。
這些智能家電來自不同的廠家,我們不想針對每一種家電都安裝一個 App,分別控制,我們希望只要一個 app 就可以控制全部智能家電。
要實現一個 app 控制所有智能家電的需要,則每個智能家電廠家都要提供一個統一的接口給 app 調用,這時 就可以考慮使用命令模式。
命令模式可將“動作的請求者”從“動作的執行者”對象中解耦出來.
在我們的例子中,動作的請求者是手機 app,動作的執行者是每個廠商的一個家電產品
2 命令模式基本介紹
命令模式(Command Pattern):在軟件設計中,我們經常需要向某些對象發送請求,但是並不知道請求的接收者是誰,也不知道被請求的操作是哪個,我們只需在程序運行時指定具體的請求接收者即可,此時,可以使用命令模式來進行設計 命名模式使得請求發送者與請求接收者消除彼此之間的耦合,讓對象之間的調用關系更加靈活,實現解耦。
在命名模式中,會將一個請求封裝為一個對象,以便使用不同參數來表示不同的請求(即命名),同時命令模式也支持可撤銷的操作。
通俗易懂的理解:將軍發布命令,士兵去執行。其中有幾個角色:將軍(命令發布者)、士兵(命令的具體執行者)、命令(連接將軍和士兵)。
Invoker 是調用者(將軍),Receiver 是被調用者(士兵),MyCommand 是命令,實現了 Command 接口,持有接收對象。
命令模式的原理類圖

對原理類圖的說明-即(命名模式的角色及職責)
Invoker 是調用者角色
Command: 是命令角色,需要執行的所有命令都在這里,可以是接口或抽象類
Receiver: 接受者角色,知道如何實施和執行一個請求相關的操作
ConcreteCommand: 將一個接受者對象與一個動作綁定,調用接受者相應的操作,實現 execute
3 命令模式解決智能生活項目
應用實例要求
編寫程序,使用命令模式 完成前面的智能家電項目
思路分析和圖解:

代碼實現
|
1
2
3
4
5
6
7
8
9
10
11
|
//創建命令接口
public
interface
Command {
//執行動作(操作)
public
void
execute();
//撤銷動作(操作)
public
void
undo();
}
|
|
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
|
public
class
LightOffCommand
implements
Command {
// 聚合 LightReceiver
LightReceive light;
// 構造器
public
LightOffCommand(LightReceiver light) {
super
();
this
.light = light;
}
@Override
public
void
execute() {
//調用接收者的方法
light.off();
}
@Override
public
void
undo() {
// 調用接收者的方法
light.on();
}
}
|
|
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
|
public
class
LightOnCommand
implements
Command {
//聚合 LightReceiver
LightReceiver light;
//構造器
public
LightOnCommand(LightReceiver light) {
super
();
this
.light = light;
}
@Override
public
void
execute() {
// 調用接收者的方法
light.on();
}
@Override
public
void
undo() {
//調用接收者的方法
light.off();
}
}
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/**
沒有任何命令,即空執行: 用於初始化每個按鈕, 當調用空命令時,對象什么都不做
其實,這樣是一種設計模式, 可以省掉對空判斷
@author Administrator
*/
public
class
NoCommand
implements
Command {
@Override
public
void
execute() {
}
@Override
public
void
undo() {
}
}
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
class
LightReceiver {
public
void
on() {
System.out.println(
" 電燈打開了.. "
);
}
public
void
off() {
System.out.println(
" 電燈關閉了.. "
);
}
}
|
|
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
|
public
class
RemoteController {
// 開 按鈕的命令數組
Command[] onCommands;
Command[] offCommands;
// 執行撤銷的命令
Command undoCommand;
// 構造器,完成對按鈕初始化
public
RemoteController() {
onCommands =
new
Command[
5
];
offCommands =
new
Command[
5
];
for
(
int
i =
0
; i <
5
; i++) {
onCommands[i] =
new
NoCommand();
offCommands[i] =
new
NoCommand();
}
}
// 給我們的按鈕設置你需要的命令
public
void
setCommand(
int
no, Command onCommand, Command offCommand) {
onCommands[no] = onCommand;
offCommands[no] = offCommand;
}
// 按下開按鈕
public
void
onButtonWasPushed(
int
no) {
// no 0 找到你按下的開的按鈕,並調用對應方法
onCommands[no].execute();
// 記錄這次的操作,用於撤銷
undoCommand = onCommands[no];
}
// 按下開按鈕
public
void
offButtonWasPushed(
int
no) {
// no 0找到你按下的關的按鈕,並調用對應方法
offCommands[no].execute();
// 記錄這次的操作,用於撤銷
undoCommand = offCommands[no];
}
// 按下撤銷按鈕
public
void
undoButtonWasPushed() {
undoCommand.undo();
}
}
|
|
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
|
public
class
Client {
public
static
void
main(String[] args) {
//使用命令設計模式,完成通過遙控器,對電燈的操作
//創建電燈的對象(接受者)
LightReceiver lightReceiver =
new
LightReceiver();
//創建電燈相關的開關命令
LightOnCommand lightOnCommand =
new
LightOnCommand(lightReceiver);
LightOffCommand lightOffCommand =
new
LightOffCommand(lightReceiver);
//需要一個遙控器
RemoteController remoteController =
new
RemoteController();
//給我們的遙控器設置命令, 比如 no = 0 是電燈的開和關的操作
remoteController.setCommand(
0
, lightOnCommand, lightOffCommand);
System.out.println(
"-------- 按下燈的開按鈕 -----------"
);
remoteController.onButtonWasPushed(
0
);
System.out.println(
"-------- 按下燈的關按鈕 -----------"
);
remoteController.offButtonWasPushed(
0
);
System.out.println(
"-------- 按下撤銷按鈕----------- "
);
remoteController.undoButtonWasPushed();
System.out.println(
"=========使用遙控器操作電視機=========="
);
TVReceiver tvReceiver =
new
TVReceiver();
TVOffCommand tvOffCommand =
new
TVOffCommand(tvReceiver);
TVOnCommand tvOnCommand =
new
TVOnCommand(tvReceiver);
//給我們的遙控器設置命令, 比如 no = 1 是電視機的開和關的操作
remoteController.setCommand(
1
, tvOnCommand, tvOffCommand);
System.out.println(
"-------- 按下電視機的開按鈕 -----------"
);
remoteController.onButtonWasPushed(
1
);
System.out.println(
"-------- 按下電視機的關按鈕 -----------"
);
remoteController.offButtonWasPushed(
1
);
System.out.println(
"-------- 按下撤銷按鈕----------- "
);
remoteController.undoButtonWasPushed();
}
}
|
