作为第三方,我正在编写一个与webservice接口的程序。我遇到的问题是,某些类最终与into /strings一样常用(例如用户),所以我需要小心我给每个类赋予哪些职责来防止依赖于其他每个mega对象的超级对象。
最好的例子是Group类(想想Facebook组)。一个组有一个AuditLog (组件),它包含LogItems。这些LogItems指定动作的目标,例如时间/等。有时这些日志的目标是另一个组,所以AuditLog需要知道如何从webservice响应提供的数据创建一个新的Group对象。这导致循环依赖关系,其中组需要知道如何创建其组件,AuditLog和AuditLog需要知道如何创建组。
那我该怎么解决呢?创建时,我可以使用依赖注入将AuditLog对象传递给组,但这不利于抽象,因为用户必须知道组对象如何在内部链接。当有许多组件必须以这种方式添加到Group对象时,这也变得不可行。我可以为AuditLog创建一个静态类:
from group import Group
from auditlog import AuditLog
ourGroup = Group(ourGroupId)
adLogs = AuditLog.getLogs(ourGroup, logType=Advertisement)
groupsWeAdvertised = [log.target for log in adLogs if isinstance(log.target, Group)]这样好多了,但还是不太理想。AuditLog是Group的一个组件--它只供Group使用,如果没有一个组,它就没有意义,因此将它划分为顶级类似乎很尴尬。不可能轻易地知道这是组的子对象(没有group就不可能存在),而不是一些顶级的服务。
有没有更理想的方法来解耦这个系统?我查看了各种软件模式,并于昨天在软件工程SE上寻找类似的问题,但我发现的所有解决方案要么涉及打破抽象,要求用户手动初始化组的组件,要么将其完全解耦到可能没有足够耦合以保持健康的地方,如上面的示例所示。
注意:我使用的是Python,所以即使循环依赖在某种程度上是理想的,Python3也不允许它。
发布于 2017-11-13 01:23:44
您可以将target属性转换为target_type和target_id,这将具有以下优点:
LogItem都具有相同的属性类型,并且可以更容易地用于任何事情。LogItem停止依赖于GroupGroup可以承载通过日志解析和在适当情况下创建Group实例的逻辑,从而结束循环依赖关系。尽管如此,它仍然认为这将是一个次优设计,因为您的类,特别是Group,似乎知道/做得太多,如果没有依赖注入,就不可能有效地测试这些代码中的任何一个。
一个更好的解决办法是做以下工作:
GroupRepositoryGroupRepository,所以建造一个工厂的细节只存在于一个地方,并且是抽象的。AuditLog (您需要的每个查询都有一个方法)Controller),在那里您将被注入GroupRepo和AuditLog实例,并根据需要使用GroupRepo来解决单个logItems中的Groups。https://softwareengineering.stackexchange.com/questions/360670
复制相似问题