Принципы, о которых вы говорите, обычно применимы к любому языку OO.Основной принцип здесь - «слабая связь».Класс, который зависит от другого класса (содержит его экземпляр и вызывает для него методы как часть своей собственной работы), на самом деле зависит только от набора функциональных возможностей, которые обеспечивает зависимость.Если класс определяет ссылку на конкретный класс, от которого он зависит, и вы хотите заменить класс другим, вам нужно не только разработать новый класс, но и изменить зависимый класс, чтобы он зависел от нового типа.Как правило, это плохо, потому что, если ваш класс зависит от многих других классов, вы должны изменить код в нескольких местах, требуя от вас протестировать все варианты использования этих объектов, чтобы убедиться, что вы не нарушили ранее работающую функциональность.
Интерфейсы были разработаны, чтобы устранить это, позволяя использовать несколько классов, не связанных между собой, взаимозаменяемо, на основе общего, принудительного набора методов, который, как вы знаете, будет реализован классом.Если вместо зависимости от класса вы зависите от интерфейса, любой класс, реализующий интерфейс, будет выполнять зависимость.Это позволяет вам написать новый класс, чтобы заменить старый, и класс, который его использует, не знает разницу.Все, что вам нужно изменить, - это код, который создает конкретную реализацию класса, заполняющего зависимость.
Это представляет проблему;Конечно, ваш класс Depender может сказать, что ему нужен IDoSomething вместо DoerClass, но если Depender знает, как создать DoerClass для использования в качестве IDoSomething, вы ничего не получили;Если вы хотите заменить DoerClass на BetterDoer, вы все равно должны изменить код Depender.Решение состоит в том, чтобы дать ответственность за предоставление классу экземпляра зависимости третьей стороне, Создателю.Класс, выбранный для этого, зависит от контекста.Если у класса, естественно, есть и Depender, и DoerClass, это очевидный выбор для их объединения.Это часто имеет место, когда у вас есть один класс, который имеет две вспомогательные зависимости, и одна зависимость также нуждается в другой.В других случаях вы можете создать Factory, которая существует для предоставления вызывающей стороне экземпляра определенного объекта, предпочтительно со всеми зависимостями, подключенными.
Если у вас есть несколько взаимозависимых классов или многоуровневых зависимостей, вы можете рассмотреть среду IoC.Контейнеры IoC предназначены для фабрик, а репозитории для DAO;они знают, как получить полностью гидратированный экземпляр ЛЮБОГО класса, требующего одну или несколько зависимостей, например, репозиторий может создать любой полностью гидратированный доменный объект из данных в БД.Это достигается тем, что ему сообщают, какой конкретный класс следует использовать для заполнения зависимости в определенной ситуации, и когда его просят предоставить класс, он создает экземпляр этого класса, предоставляя экземпляры требуемых зависимостей (и зависимостей зависимостей).Это может разрешить шаблоны, где класс A зависит от B, который зависит от C, но A не может знать о C. Инфраструктура IoC знает обо всех трех и создаст экземпляр B, даст ему новый C, а затем передаст B новомуA.