頭部導入模塊導致循環(huán)依賴問題
頭部導入模塊導致循環(huán)依賴問題
1. 不在頭部導入模塊
比如不使用類型注釋,調(diào)用時候傳入值即可,就可以避免循環(huán)依賴
2. 推遲傳遞實例
可以將 CenterHandler 的實例傳遞給 MessageHandler 時,推遲實例的創(chuàng)建或者通過依賴注入的方式進行。這種方法可以通過后期賦值的方式解決循環(huán)依賴問題。
代碼示例:
class MessageHandler:
""" 消息處理類 """
def __init__(self, monitor: Monitor) -> None:
self.publisher = EventPublisher(monitor)
self.collection_queue = multiprocessing.Queue()
self.data_collection = DataCollection(self.collection_queue, monitor.service)
self.centerhandler = None # 暫時不保存 centerhandler
def set_centerhandler(self, centerhandler: CenterHandler) -> None:
""" 設(shè)置 CenterHandler 實例 """
self.centerhandler = centerhandler
def process_message(self, message: str) -> None:
if self.centerhandler:
# 在需要使用 CenterHandler 時再訪問它
print(f"Processing message with leader address: {self.centerhandler._leader_addr}")
else:
print("CenterHandler not set yet.")
class CenterHandler(object):
""" CenterHandler類:負責處理與center有關(guān)的操作 """
def __init__(self, center: Center, monitor: Monitor, heartbeat_interval: int = 5) -> None:
self._center = center
self._zmq = center.zmq
self._leader_addr = center.leader_addr
self._addr_to_socket = center.addr_to_socket
self.messagehandler = MessageHandler(monitor) # 創(chuàng)建時不傳入 CenterHandler 實例
self.messagehandler.set_centerhandler(self) # 后期傳入 CenterHandler 實例
解釋:
- 在
MessageHandler類中,創(chuàng)建時不傳入CenterHandler實例,而是通過一個set_centerhandler方法在后期傳入CenterHandler實例。 - 這樣就避免了循環(huán)依賴,只有在
CenterHandler的實例已經(jīng)創(chuàng)建后,才能將其傳遞給MessageHandler。
3. 使用事件或回調(diào)機制
另一種方法是通過回調(diào)函數(shù)或事件機制,讓 MessageHandler 和 CenterHandler 不直接依賴對方的實例,而是通過一個外部的控制流程進行協(xié)作。
代碼示例:
class MessageHandler:
""" 消息處理類 """
def __init__(self, monitor: Monitor, on_event: Callable) -> None:
self.publisher = EventPublisher(monitor)
self.collection_queue = multiprocessing.Queue()
self.data_collection = DataCollection(self.collection_queue, monitor.service)
self.on_event = on_event # 用于事件處理的回調(diào)
def process_message(self, message: str) -> None:
# 調(diào)用回調(diào)函數(shù)來通知事件
self.on_event(message)
class CenterHandler(object):
""" CenterHandler類:負責處理與center有關(guān)的操作 """
def __init__(self, center: Center, monitor: Monitor, heartbeat_interval: int = 5) -> None:
self._center = center
self._zmq = center.zmq
self._leader_addr = center.leader_addr
self._addr_to_socket = center.addr_to_socket
self.messagehandler = MessageHandler(monitor, self.handle_event)
def handle_event(self, message: str) -> None:
""" 用于處理消息事件的回調(diào)函數(shù) """
print(f"CenterHandler handling message: {message}")
解釋:
- 在這個設(shè)計中,
MessageHandler類不再直接依賴CenterHandler的實例,而是通過回調(diào)函數(shù)來通知CenterHandler。 CenterHandler在初始化時,將自己的handle_event方法傳遞給MessageHandler,并在需要時由MessageHandler調(diào)用該方法。
4. 使用容器或管理器類
通過創(chuàng)建一個管理兩個類關(guān)系的外部容器類,來管理這些實例之間的關(guān)系,從而避免它們直接相互依賴。
class HandlerContainer:
""" 管理 MessageHandler 和 CenterHandler 的關(guān)系 """
def __init__(self, center: Center, monitor: Monitor) -> None:
self.centerhandler = CenterHandler(center, monitor)
self.messagehandler = MessageHandler(monitor)
# 在容器類中設(shè)置兩者之間的關(guān)系
self.messagehandler.set_centerhandler(self.centerhandler)
# 使用容器類來管理依賴
container = HandlerContainer(center, monitor)
解釋:
HandlerContainer類作為一個外部的管理者,負責初始化并設(shè)置CenterHandler和MessageHandler的關(guān)系。- 通過這種方式,
MessageHandler和CenterHandler之間不直接相互依賴,從而避免了循環(huán)依賴。

浙公網(wǎng)安備 33010602011771號