「補(bǔ)課」進(jìn)行時(shí):設(shè)計(jì)模式(8)——命令模式

1. 前文匯總
「補(bǔ)課」進(jìn)行時(shí):設(shè)計(jì)模式系列
2. 命令模式
命令模式是一個(gè)高內(nèi)聚的模式,其定義為:
Encapsulate a request as anobject,thereby letting you parameterize clients with differentrequests,queue or log requests,and support undoable operations.(將一個(gè)請(qǐng)求封裝成一個(gè)對(duì)象,從而讓你使用不同的請(qǐng)求把客戶端參數(shù)化,對(duì)請(qǐng)求排隊(duì)或者記錄請(qǐng)求日志,可以提供命令的撤銷和恢復(fù)功能。)

Receive: 接收者角色,這個(gè)角色就是干活的角色,命令傳遞到這里是被執(zhí)行的。 Command: 命令角色,需要執(zhí)行的所有命令都在這里聲明。 Invoker: 調(diào)用者角色,接收到命令,并執(zhí)行命令。
2.1 通用 Receiver 類
public?abstract?class?Receiver?{
????public?abstract?void?doSomething();
}
這里使用抽象類的原因是接受者可以有多個(gè),有多個(gè)就需要定義一個(gè)所有特性的抽象集合——抽象的接收者。
2.2 具體的 Receiver 類
public?class?ConcreteReceiver1?extends?Receiver?{
????@Override
????public?void?doSomething()?{
????}
}
public?class?ConcreteReceiver2?extends?Receiver?{
????@Override
????public?void?doSomething()?{
????}
}
每一個(gè)接受者都必須定義一定的業(yè)務(wù)邏輯。
2.3 抽象的 Command 類
public?abstract?class?Command?{
????public?abstract?void?execute();
}
2.4 具體的 Command 類
public?class?ConcreteCommand1?extends?Command?{
????private?Receiver?receiver;
????public?ConcreteCommand1(Receiver?receiver)?{
????????this.receiver?=?receiver;
????}
????@Override
????public?void?execute()?{
????????this.receiver.doSomething();
????}
}
public?class?ConcreteCommand2?extends?Command?{
????private?Receiver?receiver;
????public?ConcreteCommand2(Receiver?receiver)?{
????????this.receiver?=?receiver;
????}
????@Override
????public?void?execute()?{
????????this.receiver.doSomething();
????}
}
這里定義了兩個(gè)具體的 Command 實(shí)現(xiàn)類,這里的每一個(gè)具體命令類,根據(jù)構(gòu)造函數(shù)定義了具體是針對(duì)哪一個(gè)接受者發(fā)出的,同時(shí)定義了命令接收的主體。
2.5 調(diào)用者 Invoker
public?class?Invoker?{
????private?Command?command;
????public?void?setCommand(Command?command)?{
????????this.command?=?command;
????}
????public?void?action()?{
????????this.command.execute();
????}
}
調(diào)用者就是最終進(jìn)行方法調(diào)用的地方,所有的命令都會(huì)由調(diào)用者進(jìn)行調(diào)用。
2.6 測(cè)試類
public?class?Test?{
????public?static?void?main(String[]?args)?{
????????Invoker?invoker?=?new?Invoker();
????????//?定義接受者
????????Receiver?receiver?=?new?ConcreteReceiver1();
????????//?定義一個(gè)發(fā)送給接收者的命令
????????Command?command?=?new?ConcreteCommand1(receiver);
????????//?把命令交給調(diào)用者去執(zhí)行
????????invoker.setCommand(command);
????????invoker.action();
????}
}
2.7 優(yōu)點(diǎn):
類間解耦:調(diào)用者角色與接收者角色之間沒(méi)有任何依賴關(guān)系,調(diào)用者實(shí)現(xiàn)功能時(shí)只需調(diào)用 Command 抽象類的 execute 方法就可以,不需要了解到底是哪個(gè)接收者執(zhí)行。 可擴(kuò)展性:Command 的子類可以非常容易地?cái)U(kuò)展,而調(diào)用者 Invoker 和高層次的模塊 Client 不產(chǎn)生嚴(yán)重的代碼耦合。
2.8 缺點(diǎn):
命令模式也是有缺點(diǎn)的,具體請(qǐng)注意 Command 的子類:如果有 N 個(gè)命令,問(wèn)題就出來(lái)了, Command 的子類就可不是幾個(gè),而是 N 個(gè),這個(gè)類膨脹得非常大,所以在使用命令模式的時(shí)候需要謹(jǐn)慎。

