头部导入模块导致循环依赖问题

头部导入模块导致循环依赖问题

1. 不在头部导入模块

比如不使用类型注释,调用时候传入值即可,就可以避免循环依赖

2. 推迟传递实例

可以将 CenterHandler 的实例传递给 MessageHandler 时,推迟实例的创建或者通过依赖注入的方式进行。这种方法可以通过后期赋值的方式解决循环依赖问题。

代码示例:

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:
        """ 设置 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有关的操作 """

    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)  # 创建时不传入 CenterHandler 实例
        self.messagehandler.set_centerhandler(self)  # 后期传入 CenterHandler 实例

解释:

  • MessageHandler 类中,创建时不传入 CenterHandler 实例,而是通过一个 set_centerhandler 方法在后期传入 CenterHandler 实例。
  • 这样就避免了循环依赖,只有在 CenterHandler 的实例已经创建后,才能将其传递给 MessageHandler

3. 使用事件或回调机制

另一种方法是通过回调函数或事件机制,让 MessageHandlerCenterHandler 不直接依赖对方的实例,而是通过一个外部的控制流程进行协作。

代码示例:

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  # 用于事件处理的回调

    def process_message(self, message: str) -> None:
        # 调用回调函数来通知事件
        self.on_event(message)
class CenterHandler(object):
    """ CenterHandler类:负责处理与center有关的操作 """

    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:
        """ 用于处理消息事件的回调函数 """
        print(f"CenterHandler handling message: {message}")

解释:

  • 在这个设计中,MessageHandler 类不再直接依赖 CenterHandler 的实例,而是通过回调函数来通知 CenterHandler
  • CenterHandler 在初始化时,将自己的 handle_event 方法传递给 MessageHandler,并在需要时由 MessageHandler 调用该方法。

4. 使用容器或管理器类

通过创建一个管理两个类关系的外部容器类,来管理这些实例之间的关系,从而避免它们直接相互依赖。

class HandlerContainer:
    """ 管理 MessageHandler 和 CenterHandler 的关系 """

    def __init__(self, center: Center, monitor: Monitor) -> None:
        self.centerhandler = CenterHandler(center, monitor)
        self.messagehandler = MessageHandler(monitor)
        # 在容器类中设置两者之间的关系
        self.messagehandler.set_centerhandler(self.centerhandler)

# 使用容器类来管理依赖
container = HandlerContainer(center, monitor)

解释:

  • HandlerContainer 类作为一个外部的管理者,负责初始化并设置 CenterHandlerMessageHandler 的关系。
  • 通过这种方式,MessageHandlerCenterHandler 之间不直接相互依赖,从而避免了循环依赖。
posted @ 2025-04-03 16:29  零の守墓人  阅读(19)  评论(0)    收藏  举报