如何修复ItemManager和ItemValidator类之间的双向依赖关系?

时间:2019-07-19 09:54:59

标签: python oop design-patterns

我在ItemManager和ItemValidator这两个类之间具有双向关系,其中ItemManager具有ItemValidator的列表,但是每个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


1 个答案:

答案 0 :(得分:0)

具有双向关系是可以的。如果它在某种程度上伤害了您,那是不对的。

您必须考虑是否通过使Validators进入Manager而以某种方式违反单一责任原则,因为它们确实需要从Mananger调用某些方法做他们的工作。这意味着您将在Manager上调用的某些方法需要验证,而其他方法仅用于查询某些数据以进行验证。如果ValidatorManager上调用需要验证的方法并且您获得无限递归怎么办?

Manager分割成较小的对象可能是更好的选择。您仍然可以使ManagerValidators依赖于新对象,但是您确实从Manager中删除了对Validators的依赖。

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

您可以添加另一个仅用于查询的对象,并将其传递给验证器。

如果要构建树结构,则可能会有一个父节点包含一个子级集合,而一个子节点具有对其父级的引用。在这种情况下,可以拥有它。

有时候,当您想到让一个Manager类来完成所有工作并将其分解成较小的对象时,很难重新设计解决方案。 Manager是一个广义术语,我们确实过度使用它们。我们只是将与某物(例如订单)相关的所有东西都粘在一个对象中,这会使我们陷入麻烦。