Mediator 模式透過中心化的中介者物件,讓其他物件間接溝通,避免直接耦合,簡化系統維護。Command 模式則將操作封裝成物件,方便引數化、排隊和記錄操作歷史。這兩種模式各有千秋,也能結合使用,例如在事件驅動架構中,Mediator 管理事件傳遞,Command 封裝事件處理邏輯。更進一步,結合策略模式,可在執行時期切換不同演算法,提升系統彈性。實務上,層次化架構設計中,常將工廠模式嵌入底層,隔離物件建立的複雜性,服務層透過外觀模式與領域層互動,外觀內部再利用工廠例項化領域物件,展現多維度的模式整合。

行為模式:Mediator 與 Command

在軟體設計中,行為模式(Behavioral Patterns)用於定義物件之間的互動行為。這些模式描述了物件如何相互溝通和合作,以實作特定的功能。以下,我們將探討 Mediator 和 Command 兩個重要的行為模式。

Mediator 模式

Mediator 模式是一種行為模式,允許物件之間進行間接溝通,而不需要彼此之間有直接的參照。這種模式通常使用於多個物件需要相互互動的情況下,例如在事件驅動系統中。

from queue import PriorityQueue

class Mediator:
    def __init__(self):
        self.subscribers = {}

    def subscribe(self, channel, subscriber, priority):
        if channel not in self.subscribers:
            self.subscribers[channel] = PriorityQueue()
        self.subscribers[channel].put((priority, subscriber))

    def dispatch(self, channel, message):
        if channel in self.subscribers:
            queue = self.subscribers[channel]
            while not queue.empty():
                _, subscriber = queue.get()
                subscriber.handle(message)

class Component:
    def handle(self, message):
        print(f"Received message: {message}")

class ComponentA(Component):
    def handle(self, message):
        if message["type"] == "A":
            print("Component A handling message")

class ComponentB(Component):
    def handle(self, message):
        if message["type"] == "B":
            print("Component B handling message")

if __name__ == "__main__":
    mediator = Mediator()
    comp_a = ComponentA()
    comp_b = ComponentB()

    mediator.subscribe("channel1", comp_a, 5)
    mediator.subscribe("channel1", comp_b, 10)

    mediator.dispatch("channel1", {"type": "B", "payload": "Data for B"})

在上述範例中,Mediator 類別負責管理物件之間的溝通。Component 類別及其子類別(ComponentA 和 ComponentB)代表需要相互互動的物件。Mediator 使用優先權佇列(PriorityQueue)來確保訊息按照正確的順序傳遞給訂閱者。

Command 模式

Command 模式是一種行為模式,將請求封裝為物件,使得請求可以被 parameterize、queued 和 even reversed。這種模式通常使用於需要動態組合行為的系統中。

from abc import ABC, abstractmethod

class Command(ABC):
    @abstractmethod
    def execute(self):
        pass

class ConcreteCommand(Command):
    def __init__(self, receiver):
        self.receiver = receiver

    def execute(self):
        if self.receiver.state == "active":
            self.receiver.action_active()
        else:
            self.receiver.action_idle()

class Receiver:
    def __init__(self):
        self.state = "idle"

    def action_active(self):
        print("Receiver performing active action.")

    def action_idle(self):
        print("Receiver performing idle action.")

if __name__ == "__main__":
    receiver = Receiver()
    command = ConcreteCommand(receiver)
    command.execute()

在上述範例中,Command 介面定義了 execute 方法,而 ConcreteCommand 類別實作了這個介面。Receiver 類別代表需要執行動作的物件。ConcreteCommand 根據 Receiver 的狀態決定執行動作。

結合 Mediator 和 Command

在某些情況下,Mediator 和 Command 可以結合使用,以實作更複雜的行為。例如,在一個事件驅動系統中,Mediator 可以用於管理事件的傳遞,而 Command 可以用於封裝事件處理邏輯。

class EventMediator:
    def __init__(self):
        self.subscribers = {}

    def subscribe(self, event_type, subscriber):
        if event_type not in self.subscribers:
            self.subscribers[event_type] = []
        self.subscribers[event_type].append(subscriber)

    def dispatch(self, event_type, event_data):
        if event_type in self.subscribers:
            for subscriber in self.subscribers[event_type]:
                subscriber.handle(event_data)

class EventCommand(Command):
    def __init__(self, mediator, event_type, event_data):
        self.mediator = mediator
        self.event_type = event_type
        self.event_data = event_data

    def execute(self):
        self.mediator.dispatch(self.event_type, self.event_data)

if __name__ == "__main__":
    mediator = EventMediator()
    command = EventCommand(mediator, "event_type", {"data": "event_data"})
    command.execute()

在上述範例中,EventMediator 類別負責管理事件的傳遞,而 EventCommand 類別封裝了事件處理邏輯。當 EventCommand 的 execute 方法被呼叫時,它會將事件傳遞給 EventMediator,然後 EventMediator 會將事件傳遞給訂閱者。

行為模式整合:命令與策略模式

在軟體設計中,行為模式扮演著重要的角色,讓開發者能夠建立出更為靈活和可擴充套件的系統。其中,命令模式和策略模式是兩種常見的行為模式,它們可以用來解決不同問題,但也可以被整合起來,以實作更為複雜的功能。

命令模式

命令模式是一種封裝請求的模式,使得請求者和接收者之間的耦合度降低。它允許請求的引數化、排隊和記錄日誌等功能。以下是一個簡單的命令模式實作:

class Command:
    def __init__(self, receiver):
        self.receiver = receiver

    def execute(self):
        pass

class ConcreteCommand(Command):
    def execute(self):
        self.receiver.action()

class Receiver:
    def action(self):
        print("Receiver action")

receiver = Receiver()
command = ConcreteCommand(receiver)
command.execute()

在這個例子中,Command 類別是命令模式的抽象類別,而 ConcreteCommand 類別是其具體實作。Receiver 類別代表了命令的接收者。

策略模式

策略模式是一種定義一系列演算法的模式,使得它們可以相互替換。它允許客戶端在執行時選擇不同的演算法。以下是一個簡單的策略模式實作:

class Strategy:
    def execute(self, data):
        raise NotImplementedError("Subclasses must implement execute method.")

class ConcreteStrategy1(Strategy):
    def execute(self, data):
        return f"Strategy1 processing {data}"

class ConcreteStrategy2(Strategy):
    def execute(self, data):
        return f"Strategy2 processing {data}"

class Context:
    def __init__(self, strategy: Strategy):
        self.strategy = strategy

    def set_strategy(self, strategy: Strategy):
        self.strategy = strategy

    def process(self, data):
        return self.strategy.execute(data)

context = Context(ConcreteStrategy1())
print(context.process("input"))

在這個例子中,Strategy 類別是策略模式的抽象類別,而 ConcreteStrategy1ConcreteStrategy2 類別是其具體實作。Context 類別代表了策略的使用者。

整合命令和策略模式

現在,我們可以將命令模式和策略模式整合起來,以實作更為複雜的功能。以下是一個簡單的整合實作:

class Command:
    def __init__(self, receiver, strategy: Strategy):
        self.receiver = receiver
        self.strategy = strategy

    def execute(self, data):
        return self.strategy.execute(data)

class ConcreteCommand(Command):
    def __init__(self, receiver, strategy: Strategy):
        super().__init__(receiver, strategy)

class Receiver:
    def action(self):
        print("Receiver action")

class Strategy:
    def execute(self, data):
        raise NotImplementedError("Subclasses must implement execute method.")

class ConcreteStrategy1(Strategy):
    def execute(self, data):
        return f"Strategy1 processing {data}"

class ConcreteStrategy2(Strategy):
    def execute(self, data):
        return f"Strategy2 processing {data}"

receiver = Receiver()
strategy1 = ConcreteStrategy1()
strategy2 = ConcreteStrategy2()

command1 = ConcreteCommand(receiver, strategy1)
command2 = ConcreteCommand(receiver, strategy2)

print(command1.execute("input"))
print(command2.execute("input"))

在這個例子中,Command 類別被修改為接受一個 Strategy 物件作為其建構函式的引數。ConcreteCommand 類別繼承自 Command 類別,並實作了 execute 方法。Receiver 類別代表了命令的接收者,而 Strategy 類別代表了策略模式的抽象類別。

這種整合方式允許我們在執行時選擇不同的策略,並將其應用於命令模式中。這樣,我們就可以建立出更為靈活和可擴充套件的系統。

8.4 層次化模式設計的強大架構

層次化架構設計是一種構建強健且可維護系統的關鍵策略。在設計層次化架構時,玄貓強調了關注點分離的重要性。這個過程涉及將相關的責任分組到不同的層次中,每個層次透過明確定義的介面與其他層次進行互動。這種策略不僅增強了模組化,而且還方便了個別元件的演化,而不會使整個系統不穩定。

層次化架構的實踐

一種常見的方法是從建立核心領域層開始,這個層次封裝了業務邏輯。這個層次通常使用行為模式,如命令和策略模式,提供了高程度的靈活性來管理領域特定的操作。同時,應用或服務層負責協調由玄貓提供的操作,通常使用外觀和調停者模式來簡化互動。在最外層,表現或整合層處理使用者互動和外部通訊。透過玄貓,開發人員可以建立對需求變化具有彈性的系統,同時保持責任的明確分離。

繫結模式形成整合結構

在實踐中,層次化模式涉及繫結建立、結構和行為模式,以形成一個整合和適應性的結構。一種高階技術是將工廠嵌入到較低層次,以隔離物件建立的複雜性與較高層次的元件。這種建立邏輯的封裝導致了鬆散耦合的模組,它們透過明確定義的介面進行通訊。例如,一個服務層可能透過外觀呼叫領域服務,而外觀內部利用工廠例項化領域元件。以下程式碼片段進一步闡述了這種多維度的整合:

# 領域層:核心業務邏輯使用命令和策略模式
class Command:
    def execute(self):
        raise NotImplementedError("子類別必須實作execute方法")

class ProcessOrderCommand(Command):
    def __init__(self, order, strategy):
        self.order = order
        self.strategy = strategy

    def execute(self):
        return self.strategy.process(self.order)

class OrderProcessingStrategy:
    def process(self, order):
        raise NotImplementedError("子類別必須定義處理邏輯")

class StandardOrderStrategy(OrderProcessingStrategy):
    def process(self, order):
        # 實作標準訂單處理
        return f"使用標準策略處理訂單 {order.id}"

# 領域物件
class Order:
    def __init__(self, id):
        self.id = id

# 基礎設施層:使用建立模式建立領域物件
class DomainFactory:
    @staticmethod
    def create_order(order_id):
        return Order(order_id)

    @staticmethod
    def create_order_processing_command(order, strategy_type="standard"):
        if strategy_type == "standard":
            #...

玄貓的層次架構設計

玄貓的設計強調層次架構的重要性,將系統分為多個層次,每個層次都有其特定的責任和功能。這種設計方法可以提高系統的可維護性、可擴充套件性和可重用性。

領域層(Domain Layer)

領域層是系統的核心,負責封裝業務邏輯和實體物件。這一層包含了業務流程的命令和策略介面,例如 StandardOrderStrategy 類別。

基礎設施層(Infrastructure Layer)

基礎設施層負責提供底層的技術實作,例如資料庫存取、網路通訊等。這一層包含了工廠類別,例如 DomainFactory 類別,負責建立領域物件。

應用層(Application Layer)

應用層是系統的入口,負責呼叫領域層和基礎設施層的功能。這一層包含了服務外觀類別,例如 OrderServiceFacade 類別,負責封裝領域物件的建立和操作。

表現層(Presentation Layer)

表現層負責處理使用者輸入和輸出,例如 Web 頁面、API 等。這一層會呼叫應用層的功能,例如 OrderServiceFacade 類別。

從技術架構視角來看,Mediator 模式和 Command 模式各有千秋,巧妙地解決了系統中不同物件間的互動問題。Mediator 模式有效降低了物件間的耦合度,避免了複雜的網狀結構,尤其適用於事件驅動系統。Command 模式則將請求封裝成物件,實作了請求的引數化和佇列化,提升了系統的靈活性和可擴充套件性。更進一步地,結合 Mediator 和 Command 模式,可以構建更具彈性的事件驅動架構,例如利用 Mediator 管理事件傳遞,Command 封裝事件處理邏輯。然而,兩種模式也存在一些限制。Mediator 模式在處理大量物件時,Mediator 本身可能成為瓶頸。Command 模式則增加了系統的複雜度,需要仔細設計 Command 介面和具體 Command 類別。對於重視系統可維護性和擴充套件性的開發者,深入理解並應用這些模式將大有裨益。玄貓認為,隨著系統複雜度的提升,Mediator 和 Command 模式的價值將更加凸顯,值得開發者投入更多精力深入研究和實踐。