首页 > 解决方案 > 如何修复 ItemManager 和 ItemValidator 类之间的双向依赖关系?

问题描述

我在 ItemManager 和 ItemValidator 这两个类之间有双向关系,其中 ItemManager 有一个 ItemValidators 列表,但每个 ItemValidator 还采用它所属的 ItemManager 的实例,以便它可以使用 ItemManager 中的方法。

这是不好的做法吗?如果是这样,有什么更好的方法来做到这一点?

class ItemValidator:
    def __init__(self, order_manager):
        self.order_manager = order_manager

    def run(self, new_item):
        raise NotImplementedError()


class ItemValidatorImpl(ItemValidator):

    def run(self, new_item):
        existing_items = self.order_manager.list_items()  # Here is the issue as the validator needs methods from the OrderManager
        # ... validate the new item ...


class ItemManager:
    validator_classes = [ItemValidatorImpl]

    def run_validations(self, new_item):
        for validator_class in self.validator_classes:
            validator = validator_class(self)
            validator.run(new_item)

    def list_items(self):  # Method used by some validator implementations
        pass


标签: pythonoopdesign-patterns

解决方案


有双向关系是可以的。如果它以某种方式伤害了你,那就不行了。

你必须考虑一下你是否在某种程度上违反了单一职责原则,Validators因为Manager他们确实需要从Manangerdo 调用一些方法到他们的工作中。这意味着您将调用的某些方法Manager将需要验证,而其他方法仅用于查询某些数据以进行验证。如果Validator调用Manager需要验证的方法并且您得到无限递归怎么办?

将其Manager分解成更小的对象可能是更好的做法。您仍然可以让ManagerValidators依赖于新对象,但是您确实ManagerValidators.

您可以将方法分为两类:命令和查询。命令做突变而查询不做。Validaton 不应改变任何状态,因此您可能只需要进行查询。

您可以添加另一个旨在仅执行查询的对象并将其传递给验证器。

如果你正在构建一个树结构,你可能会有一个包含一组子节点的父节点和一个引用它的父节点的子节点。在这种情况下,拥有它很好。

有时,当您认为让一个Manager类完成所有工作并将其分解为更小的对象可能很困难时,很难重新设计您的解决方案。Manager是一个广义的术语,我们确实过度使用它们。我们只是将与某事物(如 Order)相关的所有内容都粘贴到一个对象中,这会给我们带来麻烦。


推荐阅读