我试图编写使用依赖注入的代码,既可以进行模拟,也可以具有更清晰、更明确的设计。
我经常遇到一个问题,我认为这是很常见的,但我还没有找到任何能帮助我克服它的东西。问题是A对象依赖于B,B依赖于C,C依赖于D,以此类推,在这个链中可能会有很多链接。
看起来,为了实践依赖注入,A需要在其构造函数中请求B、C、D等(或者对于创建它们所依赖的实例的对象,如BFactory、CFactory等)。为了论证,我假设这些依赖关系不是可选的或仅限于特定方法,因此不能使用setter注入或方法参数注入。
这让我想到长链式依赖对象是一种反模式。从抽象意义上讲,它与箭头反模式有一些共同之处。长链式依赖对象形成了一个箭头形状的序列图。
因此,也许我应该避免这种做法,并遵循“Python之禅”中的建议,“平坦比嵌套好”。这建议采用一种设计,其中主程序创建两个或三个对象,它们合作产生返回给主程序的结果,然后主程序创建另外两个或三个对象来完成下一阶段的工作,以此类推。
我感觉这种代码易于理解和调试,并使依赖注入变得容易。但它似乎违反了“告诉,不要问”的原则,并使主程序太臃肿。我喜欢主程序如此小而明显,以至于它不需要单元测试。如果所有东西都以A开头并以A结尾,那么它就是A的责任,“告诉,不要问”告诉我,如果A是一个正在计费的客户,并且客户拥有启动计费过程所需的数据以及最后需要发送发票的电子邮件地址,那么A应该自己完成工作(主程序只能调用Customer.billYourself()),而不是通过给主程序一堆发票和一个电子邮件地址来将责任交还给主程序。
所以,我应该避免依赖链,以使DI更容易,还是应该因为“告诉,不要问”而接受它们呢?
我经常遇到一个问题,我认为这是很常见的,但我还没有找到任何能帮助我克服它的东西。问题是A对象依赖于B,B依赖于C,C依赖于D,以此类推,在这个链中可能会有很多链接。
看起来,为了实践依赖注入,A需要在其构造函数中请求B、C、D等(或者对于创建它们所依赖的实例的对象,如BFactory、CFactory等)。为了论证,我假设这些依赖关系不是可选的或仅限于特定方法,因此不能使用setter注入或方法参数注入。
这让我想到长链式依赖对象是一种反模式。从抽象意义上讲,它与箭头反模式有一些共同之处。长链式依赖对象形成了一个箭头形状的序列图。
因此,也许我应该避免这种做法,并遵循“Python之禅”中的建议,“平坦比嵌套好”。这建议采用一种设计,其中主程序创建两个或三个对象,它们合作产生返回给主程序的结果,然后主程序创建另外两个或三个对象来完成下一阶段的工作,以此类推。
我感觉这种代码易于理解和调试,并使依赖注入变得容易。但它似乎违反了“告诉,不要问”的原则,并使主程序太臃肿。我喜欢主程序如此小而明显,以至于它不需要单元测试。如果所有东西都以A开头并以A结尾,那么它就是A的责任,“告诉,不要问”告诉我,如果A是一个正在计费的客户,并且客户拥有启动计费过程所需的数据以及最后需要发送发票的电子邮件地址,那么A应该自己完成工作(主程序只能调用Customer.billYourself()),而不是通过给主程序一堆发票和一个电子邮件地址来将责任交还给主程序。
所以,我应该避免依赖链,以使DI更容易,还是应该因为“告诉,不要问”而接受它们呢?