Добрый день!
В фреймворках например, в том же Spring, реализован такой принцип, как DI (dependency injection). Все сводится к тому, что вы можете внедрить интерфейс, вместо самой реализации. Это упрощает процесс тестирования и разработки, так как вы можете "подсунуть" другую реализацию этого интерфейса. Например, на production вам нужно подключиться к реальной БД и использовать соответствующие репозитории, а во время тестирования вы можете замокать другие реализации интерфейса.
Допустим, что у вас есть интерфейс IServer с методом connect()
А реализации у него могут быть разные. Например,
FtpConnect implements IServer, SshConnect implements IServer
Соответственно, внедрив зависимость IServer в код, вы можете указать какая реализация данного интерфейса должны быть внедрена.
Посмотрите на фреймворки:
Guice -
https://www.baeldung.com/guice
Dagger -
https://dagger.dev/