На самом деле, этот вопрос является примером распространенного заблуждения о «программировании на интерфейсах».
Видите ли, этот является очень хорошим принципом, но он действительно не означает, что многие думают, что это означает!
«Программа для интерфейса, а не для реализации» (из книги GoF) означает только то, что вы не должны стараться изо всех сил создавать отдельных интерфейсов для всего. Если у вас есть объект ArrayList
, тогда объявите тип переменной / поля / параметра / возвращаемого типа List
. В этом случае код клиента будет работать только с типом интерфейса.
В книге «Эффективная Ява» Джошуа Блоха этот принцип более четко выражен в «Пункте 52: Обращайтесь к объектам по их интерфейсам». Там даже написано жирным шрифтом:
Вполне уместно ссылаться на объект классом, а не
интерфейс, если соответствующий интерфейс не существует.
В модульном тестировании ситуация полностью зависит от возможностей используемого инструмента насмешки. С помощью моего собственного инструмента JMockit я могу писать модульные тесты так же легко для кода, который использует интерфейсы и Dependency Injection, как для кода, который использует конечные классы, созданные изнутри тестируемого кода.
Итак, для меня ответ таков: всегда используйте интерфейсы, которые уже существуют, но избегайте создания новых, если для этого нет веских оснований (и testable , сам по себе, не должен быть одним ).