Python 實作命令模式、中介者模式和解釋器模式

2024.06.05

今天介紹三種行為型設計模式:指令模式、中介者模式、解釋者模式。

1.命令模式

它將請求封裝成一個對象,從而使得可以用不同的請求對客戶進行參數化。命令模式也支援撤銷操作。

(1) 命令模式的結構

命令模式的核心是命令物件和接收者物件之間的關係。命令物件封裝了一個特定的請求,包含了執行該請求的方法。接收者物件負責實際執行請求。

以下是命令模式的基本結構:

# 命令对象接口
class Command:
    def execute(self):
        pass

    def undo(self):
        pass

# 具体命令对象类
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()

# 接收者对象类
class Receiver:
    def action_a(self):
        print("接收者执行动作A")

    def action_b(self):
        print("接收者执行动作B")

    def undo_action_a(self):
        print("接收者撤销动作A")

    def undo_action_b(self):
        print("接收者撤销动作B")

# 客户端代码
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()
  • 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.

(2) 命令模式的應用場景

命令模式適用於以下場景:

  • 需要將請求的發送者和接收者解耦,使得它們可以獨立地變化。
  • 需要支援撤銷操作。

(3) 命令模式的優點

  • 命令模式將請求的發送者和接收者解耦,使得它們可以獨立地變化。
  • 命令模式支援撤銷操作。
  • 命令模式遵循開閉原則,新的命令物件可以輕鬆地添加到系統中,而不會影響到原有的程式碼。

(4) 命令模式的缺點

  • 在命令模式中,命令物件和接收者物件之間存在循環依賴的關係,可能會導致循環引用的問題。

2.中介者模式

它透過封裝一系列物件之間的交互,將物件之間的耦合度降低到最低。中介者模式將對象之間的交互作用轉移給中介者對象,使得對象之間不再直接互相引用。

(1) 中介者模式的結構

中介者模式的核心是中介者對象,它封裝了一系列物件之間的互動邏輯。中介者物件通常包含一個或多個接口,用於與其他物件進行通訊。

以下是中介者模式的基本結構:

# 中介者接口
class Mediator:
    def send(self, message, colleague):
        pass

# 同事类接口
class Colleague:
    def set_mediator(self, mediator):
        pass

    def send(self, message):
        pass

    def receive(self, message):
        pass

# 具体中介者类
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)

# 具体同事类
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)

# 客户端代码
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!")
  • 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.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.

(2) 中介者模式的應用場景

中介者模式適用於以下場景:

  • 一組物件之間存在複雜的交互關係,導致物件之間的耦合度較高。
  • 要求物件之間的交互邏輯可以靈活地改變,而不需要修改物件之間的引用關係。

(3) 中介者模式的優點

  • 中介者模式將物件之間的互動邏輯封裝到中介者物件中,從而使得物件之間的耦合度降低到最低。
  • 中介者模式使得物件之間的互動邏輯可以靈活地改變,而不需要修改物件之間的引用關係。
  • 中介者模式遵循開閉原則,新的同事類別可以輕易地加入系統中,而不會影響原有的程式碼。

(4) 中介者模式的缺點

  • 在中介者模式中,中介者物件通常需要知道所有的同事類,可能會導致中介者物件的職責過重。

3.解釋器模式

它定義了一種語言的文法,並解析相應的語句。解釋器模式透過定義語言的文法,將文法中的每個規則映射到一個類,然後透過遞歸的方式解析語句。

(1) 解釋器模式的結構

解釋器模式的核心是解釋器類,它封裝了解釋語句的邏輯。解釋器類別通常包含一個或多個解釋方法,用於解釋語句的不同部分。

以下是解釋器模式的基本結構:

# 抽象表达式类
class AbstractExpression:
    def interpret(self, context):
        pass

# 终结符表达式类
class TerminalExpression(AbstractExpression):
    def interpret(self, context):
        # 解释终结符表达式的逻辑
        pass

# 非终结符表达式类
class NonterminalExpression(AbstractExpression):
    def __init__(self):
        self.expressions = []

    def add_expression(self, expression):
        self.expressions.append(expression)

    def interpret(self, context):
        # 解释非终结符表达式的逻辑
        for expression in self.expressions:
            expression.interpret(context)

# 上下文类
class Context:
    def __init__(self):
        self.input = None
        self.output = None

# 客户端代码
if __name__ == "__main__":
    context = Context()

    # 构建语法树
    expression1 = TerminalExpression()
    expression2 = NonterminalExpression()
    expression3 = TerminalExpression()

    expression2.add_expression(expression1)
    expression2.add_expression(expression3)

    # 解释语句
    expression2.interpret(context)
  • 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.

(2) 解譯器模式的應用場景

解釋器模式適用於以下場景:

  • 一種語言的文法比較簡單,而且文法的規則可以用類別來表達。
  • 需要解析和執行一種特定的語言。

(3) 解譯器模式的優點

  • 解釋器模式將解釋語句的邏輯封裝到解釋器類別中,使得解釋語句的邏輯可以靈活地改變。
  • 解釋器模式遵循開閉原則,新的解釋器類別可以輕鬆地添加到系統中,而不會影響到原有的程式碼。

(4) 解譯器模式的缺點

  • 在解釋器模式中,解釋器類別通常需要知道所有的語法規則,可能會導致解釋器類別的職責過重。