“行為請求者”與“行為實(shí)現(xiàn)者”通常呈現(xiàn)一種“緊耦合”州邢。但在某些場合,比如要對行為進(jìn)行“記錄辙诞、撤銷/重做佃声、事務(wù)”等處理,這種無法抵御變化的緊耦合是不合適的倘要。在這種情況下,如何將“行為請求者”與“行為實(shí)現(xiàn)者”解耦十拣?將一組行為抽象為對象封拧,實(shí)現(xiàn)二者之間的松耦合。這就是命令模式(Command Pattern)
命令模式應(yīng)該有一下幾個角色:
Command:
定義命令的接口夭问,聲明執(zhí)行的方法泽西,可以理解為一個基類。
ConcreteCommand:
命令接口實(shí)現(xiàn)對象缰趋,通常會持有接收者捧杉,并調(diào)用接收者的功能來完成命令要執(zhí)行的操作。
Receiver:
接收者秘血,真正執(zhí)行命令的對象味抖。任何類都可能成為一個接收者,只要它能夠?qū)崿F(xiàn)命令要求實(shí)現(xiàn)的相應(yīng)功能灰粮。
Invoker:
要求命令對象執(zhí)行請求仔涩,通常會持有命令對象,可以持有很多的命令對象粘舟,相當(dāng)于使用命令對象的入口熔脂。
Client:
創(chuàng)建具體的命令對象佩研,組裝命令對象和接收者,或許霞揉,把這個Client稱為裝配者會更好理解旬薯,因?yàn)檎嬲褂妹畹目蛻舳耸菑腎nvoker來觸發(fā)執(zhí)行。
示例code:
# -*- coding:utf-8 -*-
class Command:
"""聲明命令模式接口"""
def __init__(self, obj):
self.obj = obj
def execute(self):
pass
class ConcreteCommand(Command):
"""實(shí)現(xiàn)命令模式接口"""
def execute(self):
self.obj.run()
class Invoker:
"""接受命令并執(zhí)行命令的接口"""
def __init__(self):
self._commands = []
def add_command(self, cmd):
self._commands.append(cmd)
def remove_command(self, cmd):
self._commands.remove(cmd)
def run_command(self):
for cmd in self._commands:
cmd.execute()
class Receiver:
"""具體動作"""
def __init__(self, word):
self.word = word
def run(self):
print(self.word)
def client():
"""裝配者"""
test = Invoker()
cmd1 = ConcreteCommand(Receiver('命令一'))
test.add_command(cmd1)
cmd2 = ConcreteCommand(Receiver('命令二'))
test.add_command(cmd2)
cmd3 = ConcreteCommand(Receiver('命令三'))
test.add_command(cmd3)
test.run_command()
if __name__ == '__main__':
client()
--------------------------
命令一
命令二
命令三
命令模式的幾個核心角色及其分工:
Command(命令基類):主要聲明抽象命令類的接口
ConcreteCommand(命令實(shí)現(xiàn)):復(fù)寫基類中聲明的接口适秩,實(shí)現(xiàn)具體的調(diào)用功能
Receiver(命令的內(nèi)容):具體執(zhí)行動作的對象
Invoker(命令調(diào)度和執(zhí)行):全部命令的執(zhí)行和調(diào)度入口
Client(命令裝配者):創(chuàng)建具體的命令對象绊序,組裝命令對象和接收者