Python 實(shí)現(xiàn)命令模式、中介者模式和解釋器模式
今天介紹三種行為型設(shè)計(jì)模式:命令模式、中介者模式和解釋器模式。
1.命令模式
它將請(qǐng)求封裝成一個(gè)對(duì)象,從而使得可以用不同的請(qǐng)求對(duì)客戶(hù)進(jìn)行參數(shù)化。命令模式也支持撤銷(xiāo)操作。
(1) 命令模式的結(jié)構(gòu)
命令模式的核心是命令對(duì)象和接收者對(duì)象之間的關(guān)系。命令對(duì)象封裝了一個(gè)特定的請(qǐng)求,包含了執(zhí)行該請(qǐng)求的方法。接收者對(duì)象負(fù)責(zé)實(shí)際執(zhí)行請(qǐng)求。
以下是命令模式的基本結(jié)構(gòu):
# 命令對(duì)象接口
class Command:
def execute(self):
pass
def undo(self):
pass
# 具體命令對(duì)象類(lèi)
class ConcreteCommandA(Command):
def __init__(self, receiver):
self.receiver = receiver
def execute(self):
self.receiver.action_a()
def undo(self):
self.receiver.undo_action_a()
class ConcreteCommandB(Command):
def __init__(self, receiver):
self.receiver = receiver
def execute(self):
self.receiver.action_b()
def undo(self):
self.receiver.undo_action_b()
# 接收者對(duì)象類(lèi)
class Receiver:
def action_a(self):
print("接收者執(zhí)行動(dòng)作A")
def action_b(self):
print("接收者執(zhí)行動(dòng)作B")
def undo_action_a(self):
print("接收者撤銷(xiāo)動(dòng)作A")
def undo_action_b(self):
print("接收者撤銷(xiāo)動(dòng)作B")
# 客戶(hù)端代碼
if __name__ == "__main__":
receiver = Receiver()
command_a = ConcreteCommandA(receiver)
command_b = ConcreteCommandB(receiver)
invoker = Invoker()
invoker.set_command(command_a)
invoker.execute_command()
invoker.set_command(command_b)
invoker.execute_command()
(2) 命令模式的應(yīng)用場(chǎng)景
命令模式適用于以下場(chǎng)景:
- 需要將請(qǐng)求的發(fā)送者和接收者解耦,使得它們可以獨(dú)立地變化。
- 需要支持撤銷(xiāo)操作。
(3) 命令模式的優(yōu)點(diǎn)
- 命令模式將請(qǐng)求的發(fā)送者和接收者解耦,使得它們可以獨(dú)立地變化。
- 命令模式支持撤銷(xiāo)操作。
- 命令模式遵循開(kāi)閉原則,新的命令對(duì)象可以很容易地添加到系統(tǒng)中,而不會(huì)影響到原有的代碼。
(4) 命令模式的缺點(diǎn)
- 命令模式中,命令對(duì)象和接收者對(duì)象之間存在循環(huán)依賴(lài)的關(guān)系,可能會(huì)導(dǎo)致循環(huán)引用的問(wèn)題。
2.中介者模式
它通過(guò)封裝一系列對(duì)象之間的交互,將對(duì)象之間的耦合度降低到最低。中介者模式將對(duì)象之間的交互轉(zhuǎn)移給中介者對(duì)象,從而使得對(duì)象之間不再直接相互引用。
(1) 中介者模式的結(jié)構(gòu)
中介者模式的核心是中介者對(duì)象,它封裝了一系列對(duì)象之間的交互邏輯。中介者對(duì)象通常包含一個(gè)或多個(gè)接口,用于與其他對(duì)象進(jìn)行通信。
以下是中介者模式的基本結(jié)構(gòu):
# 中介者接口
class Mediator:
def send(self, message, colleague):
pass
# 同事類(lèi)接口
class Colleague:
def set_mediator(self, mediator):
pass
def send(self, message):
pass
def receive(self, message):
pass
# 具體中介者類(lèi)
class ConcreteMediator(Mediator):
def __init__(self):
self.colleague_a = None
self.colleague_b = None
def set_colleague_a(self, colleague_a):
self.colleague_a = colleague_a
def set_colleague_b(self, colleague_b):
self.colleague_b = colleague_b
def send(self, message, colleague):
if colleague == self.colleague_a:
self.colleague_b.receive(message)
elif colleague == self.colleague_b:
self.colleague_a.receive(message)
# 具體同事類(lèi)
class ConcreteColleagueA(Colleague):
def __init__(self, mediator):
self.mediator = mediator
def set_mediator(self, mediator):
self.mediator = mediator
def send(self, message):
self.mediator.send(message, self)
def receive(self, message):
print("同事A收到消息:", message)
class ConcreteColleagueB(Colleague):
def __init__(self, mediator):
self.mediator = mediator
def set_mediator(self, mediator):
self.mediator = mediator
def send(self, message):
self.mediator.send(message, self)
def receive(self, message):
print("同事B收到消息:", message)
# 客戶(hù)端代碼
if __name__ == "__main__":
mediator = ConcreteMediator()
colleague_a = ConcreteColleagueA(mediator)
colleague_b = ConcreteColleagueB(mediator)
mediator.set_colleague_a(colleague_a)
mediator.set_colleague_b(colleague_b)
colleague_a.send("Hello, colleague B!")
colleague_b.send("Hi, colleague A!")
(2) 中介者模式的應(yīng)用場(chǎng)景
中介者模式適用于以下場(chǎng)景:
- 一組對(duì)象之間存在復(fù)雜的交互關(guān)系,導(dǎo)致對(duì)象之間的耦合度較高。
- 要求對(duì)象之間的交互邏輯可以靈活地改變,而不需要修改對(duì)象之間的引用關(guān)系。
(3) 中介者模式的優(yōu)點(diǎn)
- 中介者模式將對(duì)象之間的交互邏輯封裝到中介者對(duì)象中,從而使得對(duì)象之間的耦合度降低到最低。
- 中介者模式使得對(duì)象之間的交互邏輯可以靈活地改變,而不需要修改對(duì)象之間的引用關(guān)系。
- 中介者模式遵循開(kāi)閉原則,新的同事類(lèi)可以很容易地添加到系統(tǒng)中,而不會(huì)影響到原有的代碼。
(4) 中介者模式的缺點(diǎn)
- 中介者模式中,中介者對(duì)象通常需要知道所有的同事類(lèi),可能會(huì)導(dǎo)致中介者對(duì)象的職責(zé)過(guò)重。
3.解釋器模式
它定義了一種語(yǔ)言的文法,并解析相應(yīng)的語(yǔ)句。解釋器模式通過(guò)定義語(yǔ)言的文法,將文法中的每個(gè)規(guī)則映射到一個(gè)類(lèi),然后通過(guò)遞歸的方式解析語(yǔ)句。
(1) 解釋器模式的結(jié)構(gòu)
解釋器模式的核心是解釋器類(lèi),它封裝了解釋語(yǔ)句的邏輯。解釋器類(lèi)通常包含一個(gè)或多個(gè)解釋方法,用于解釋語(yǔ)句的不同部分。
以下是解釋器模式的基本結(jié)構(gòu):
# 抽象表達(dá)式類(lèi)
class AbstractExpression:
def interpret(self, context):
pass
# 終結(jié)符表達(dá)式類(lèi)
class TerminalExpression(AbstractExpression):
def interpret(self, context):
# 解釋終結(jié)符表達(dá)式的邏輯
pass
# 非終結(jié)符表達(dá)式類(lèi)
class NonterminalExpression(AbstractExpression):
def __init__(self):
self.expressions = []
def add_expression(self, expression):
self.expressions.append(expression)
def interpret(self, context):
# 解釋非終結(jié)符表達(dá)式的邏輯
for expression in self.expressions:
expression.interpret(context)
# 上下文類(lèi)
class Context:
def __init__(self):
self.input = None
self.output = None
# 客戶(hù)端代碼
if __name__ == "__main__":
context = Context()
# 構(gòu)建語(yǔ)法樹(shù)
expression1 = TerminalExpression()
expression2 = NonterminalExpression()
expression3 = TerminalExpression()
expression2.add_expression(expression1)
expression2.add_expression(expression3)
# 解釋語(yǔ)句
expression2.interpret(context)
(2) 解釋器模式的應(yīng)用場(chǎng)景
解釋器模式適用于以下場(chǎng)景:
- 一種語(yǔ)言的文法比較簡(jiǎn)單,且文法的規(guī)則可以通過(guò)類(lèi)來(lái)表達(dá)。
- 需要解析和執(zhí)行一種特定的語(yǔ)言。
(3) 解釋器模式的優(yōu)點(diǎn)
- 解釋器模式將解釋語(yǔ)句的邏輯封裝到解釋器類(lèi)中,使得解釋語(yǔ)句的邏輯可以靈活地改變。
- 解釋器模式遵循開(kāi)閉原則,新的解釋器類(lèi)可以很容易地添加到系統(tǒng)中,而不會(huì)影響到原有的代碼。
(4) 解釋器模式的缺點(diǎn)
- 解釋器模式中,解釋器類(lèi)通常需要知道所有的語(yǔ)法規(guī)則,可能會(huì)導(dǎo)致解釋器類(lèi)的職責(zé)過(guò)重。