Некоторое время назад я написал сообщение в блоге на эту тему: Понимание кода: статические и динамические зависимости . По сути, вам необходимо различать статические зависимости , которые разрешаются компилятором во время компиляции, и динамические зависимости , которые разрешаются средой выполнения (JVM или CLR). ) во время выполнения.
статические зависимости обычно вызываются вызовами статических / финальных методов, чтением / записью в поле, в определении класса C реализация интерфейса I от C ... все эти ассоциации между элементами кода, которые могут быть явно найдены в байт-коде и исходном коде.
динамические зависимости обычно вызываются всем, что абстрагирует вызов метода во время компиляции, например, вызовами абстрактных / виртуальных методов (полиморфизм), переменных или параметров, типизированных интерфейсом (класс реализации абстрагируется в время компиляции), но также делегаты (.NET) или указатели на функции (C ++).
В большинстве случаев, когда вы читаете о зависимостях в литературе, они говорят о статических зависимостях .
A статические зависимости является прямой (то есть не транзитивной). Инструмент, подобный NDepend , о котором я упоминаю в сообщении в блоге, также может выводить косвенные (или называть это транзитивные) статические зависимости из набора прямых статических зависимостей .
Идея, которую я защищаю в посте блога, заключается в том, что , когда дело доходит до понимания и сопровождения программы, нужно сосредоточиться в основном на статических зависимостях, найденных в исходном коде. . Действительно, средства абстракций используются, ну ... абстрактно, для реализации для вызывающих. Это делает исходный код намного проще в разработке и обслуживании Однако существуют ситуации, обычно во время отладки, когда нужно знать, что на самом деле стоит за абстракцией во время выполнения.