许多文章/书籍....谈论阶级或包依赖,很少解释它是什么。我确实找到了一些定义,但它们各不相同,可能并未涵盖所有情况。 E.g:
要考虑的其他方面是方法参数,依赖注入,面向方面编程,泛型。还有其他方面吗?
那么,你能否给出一个(正式的)关于类之间以及包含所有这些案例和方面的包之间的依赖关系的定义吗?
答案 0 :(得分:3)
如果要求在控制或依赖注入反转的上下文中依赖,那么,您可能对直接相互交互的类感兴趣。这意味着主要是构造函数参数和属性。
在UML域图的上下文中,您可能对“真实世界”依赖感兴趣。狗需要食物。这是一种依赖。狗的Bark()
方法返回一个Sound
对象:在UML域模型中,这不是你感兴趣的东西。狗不依赖声音存在。
你也可以对此进行哲学思考:所有阶级都相互依赖,以实现共同的目标;一个(希望)很棒的软件。
所以,总而言之,依赖或耦合不是问题或不是问题。它实际上取决于上下文和耦合的度(弱,强)。我认为这解释了为什么存在许多不同的依赖定义。
答案 1 :(得分:2)
我刚才写了一篇关于该主题的博文:Understanding Code: Static vs Dynamic Dependencies。基本上你需要在静态依赖项,编译时由编译器解析的那些和动态依赖项之间做出改变,那些是由运行时解析的(JVM)或CLR)在运行时。
静态依赖通常是通过调用static / final方法,读/写字段,在类C的定义中引发的接口I的实现C ...所有这些代码元素之间的关联,可以在字节码和源代码中明确找到。
动态依赖通常是由在编译时抽象方法调用的所有东西引起的,比如调用抽象/虚方法(多态),用接口键入的变量或参数(实现类是抽象的)在编译时),还有委托(.NET)或函数指针(C ++)。
大多数情况下,当您阅读文献中的依赖关系时,他们会谈论静态依赖。
静态依赖是直接的(意思是不可传递的)。我在博客文章中提到的像NDepend这样的工具也可以从直接静态依赖项的集合推断出间接(或称之为传递)静态依赖。
我在博客文章中辩护的想法是在理解和维护程序时,需要主要关注静态依赖项,即源代码中的静态依赖项。。实际上,抽象设施习惯用于呼叫者的抽象实现。这使得源代码更容易开发和维护。但是有些情况,通常是在调试时,需要知道运行时抽象背后的真正原因。
答案 2 :(得分:1)
这篇文章是关于静态依赖 - 对于动态依赖和差异,请参阅 Patrick Smacchia的回答。
以一种易于理解的方式:实体(类或包)A取决于实体B,当A不能单独使用而不用B时。
继承,聚合,组合,所有这些都引入了相关实体之间的依赖关系。
所以不存在对接口的依赖吗?
有,但界面只作为胶水。
继承怎么样?
见上文。
所以依赖是一种传递关系,不仅仅是在包上,还在类级别上?
是的。
但你如何定义“依赖”?
见上面“易于理解”的定义。也与您发布的第3个定义有关。
更新
因此,如果您在包P1中有接口A,而包P2中的C类使用A作为
class C implements A
或class C<E extends A>
,然后C取决于A,P2取决于P1。
但是如果接口A是由B类和C类程序针对接口A实现的,并且只通过依赖注入使用B,则C仍然(静态!)仅依赖于A,而不是B,因为依赖注入点是它不会使胶合组件依赖。