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 類別是策略模式的抽象類別,而 ConcreteStrategy1 和 ConcreteStrategy2 類別是其具體實作。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 模式的價值將更加凸顯,值得開發者投入更多精力深入研究和實踐。