Программирование на интерфейсах: Вы пишете интерфейсы для всех классов домена?
Я согласен, что программирование против интерфейсов является хорошей практикой. В большинстве случаев в "интерфейсе" Java в этом смысле означает интерфейс построения языка, так что вы пишете интерфейс и класс реализации, а чаще всего используете интерфейс вместо класса реализации.
Интересно, является ли это хорошей практикой для написания моделей домена. Так, например, если у вас есть клиент домена класса, и у каждого клиента может быть список ордеров, вы бы обычно писали интерфейсы ICustomer и IOrder. А также у Клиента есть список IOrders вместо Заказов? Или вы бы использовали интерфейсы в модели домена, только если он действительно управляется доменом, например. у вас есть как минимум два разных типа ордеров? Другими словами, используете ли вы интерфейсы только из-за технических потребностей в модели домена или только тогда, когда это действительно подходит для фактического домена?
Ответы
Ответ 1
Написание интерфейсов "только потому, что" поражает меня как пустую трату времени и энергии, не говоря уже о нарушении принципа KISS.
Я пишу их, когда они на самом деле полезны для представления общего поведения связанных классов, а не только как фантастический заголовочный файл.
Ответ 2
Не разрабатывайте свою систему. Если вы обнаружите, что у вас есть несколько типов ордеров, и считайте целесообразным объявить интерфейс для ордеров, чем рефакторинг, когда возникнет такая необходимость. Для доменных моделей вероятность высока, что конкретный интерфейс сильно изменится в течение всего жизненного цикла разработки, поэтому редко бывает полезно написать интерфейс раньше.
Ответ 3
Интерфейсы - отличный способ изолировать компоненты для целей единичного тестирования и общего управления зависимостями. Говоря это, я часто предпочитаю абстрактные классы, поэтому по крайней мере некоторые из распространенного поведения выгружаются там, а не заставляют некоторые из дублирования, которые приносят интерфейсы. Современные IDE позволяют быстро и легко создавать интерфейсы, поэтому они не так много работают: -)
Ответ 4
Нет, я использую только интерфейсы в объектах Domain, чтобы они слабо связаны. Для меня основной крючок разработки моего собственного кода с интерфейсами заключается в том, что я могу легко создавать макеты при выполнении Unit Testing. Я не вижу смысла в насмешливых объектах домена, поскольку у них нет тех же зависимостей, что и у уровня сервиса или класса DAO.
Это, конечно, не означает отклонения от использования интерфейсов в объектах домена. Используйте, где это необходимо. Например, в последнее время я работал над webapp, где различные типы объектов домена соответствуют страницам permalink, в которых пользователи могут оставлять комментарии. Таким образом, каждая из этих доменных объектов теперь реализует интерфейс "Commentable". Все код, основанный на комментариях, затем запрограммирован на интерфейс Commentable вместо объектов домена.
Ответ 5
Я бы рекомендовал оставаться стройным и гибким - ничего не делайте, пока вам это не понадобится, а затем пусть ваша IDE сделает рефакторинг для вас, когда вам это нужно.
Его довольно тривиально в IDEA/eclipse, чтобы превратить конкретный класс в интерфейс, когда вы решите, что вам нужно.
Затем используйте инъекцию зависимостей с Spring или Guice, если у вас есть много реализаций интерфейса для ввода в места вашего кода, вы используете "новый"
Ответ 6
Собственно, этот вопрос является примером общего недоразумения в отношении "программирования против интерфейсов".
Вы видите, это очень хороший принцип, но это не значит, что многие думают, что это значит!
"Программа для интерфейса, а не реализация" (из книги GoF) означает именно это, а не то, что вы должны изо всех сил создавать отдельные интерфейсы для всего. Если у вас есть объект ArrayList
, тогда объявите тип переменной /field/parameter/return как тип List
. Клиентский код будет обрабатывать только тип интерфейса.
В книге "Эффективная Ява" от Джошуа Блоха принцип выражен более четко, в разделе "Пункт 52: обратитесь к объектам по их интерфейсам". Он даже говорит жирным шрифтом:
Весьма целесообразно ссылаться на объект классом, а не на интерфейса, если не существует соответствующего интерфейса.
Для модульного тестирования ситуация полностью зависит от возможностей используемого инструмента для издевательств. С помощью моего собственного инструмента JMockit я могу написать модульные тесты так же легко для кода, который использует интерфейсы и Injection Dependency, как для кода, который использует конечные классы, созданные изнутри тестируемого кода.
Итак, для меня ответ: всегда используйте уже существующие интерфейсы, но не создавайте новые, если нет веских оснований для этого (и само проверяемость не должна быть одной).
Ответ 7
Написание интерфейса, прежде чем он понадобится (для тестирования или архитектуры), является излишним.
Кроме того, написание интерфейса вручную - пустая трата времени. Вы можете использовать рефакторинг Resharper "Pull Members", чтобы он мог создать новый интерфейс из определенного класса за считанные секунды. Другие инструменты рефакторинга, которые интегрируются с IDE, также должны иметь аналогичную функциональность.
Ответ 8
Обычно я использую только интерфейсы, где это имеет смысл в небольших проектах. Однако моя последняя работа имеет большой проект, в котором почти каждый объект домена имеет интерфейс. Вероятно, это излишне, и это определенно раздражает, но способ, которым мы тестируем и используем Spring для зависимой инъекции, требует его.
Ответ 9
В основном мы пишем веб-приложения с Wicket, Spring и Hibernate, и мы используем интерфейсы для Spring Beans, например. Услуги и DAO. Для этих классов интерфейсы имеют смысл. Но мы также используем интерфейсы для каждого отдельного класса домена, и я думаю, что это просто избыточно.
Ответ 10
Даже если вы уверены, что будет только один конкретный тип объекта модели, использование интерфейсов упростит насмешку и тестирование (но в наши дни есть фреймворки, которые могут помочь вам генерировать макетные классы автоматически, даже для конкретных Java-классы - Mockito, JTestR, Spring, Groovy...)
Но я все чаще использую интерфейсы для сервисов, так как еще более важно имитировать их во время тестирования, а программирование на интерфейсах помогает вам думать о таких вещах, как инкапсуляция.
Ответ 11
Написание интерфейсов для классов домена может иметь смысл, если вы используете его для модульного тестирования. Мы используем объекты Mock в модульном тестировании. Итак, если у вас есть интерфейс для объекта домена, а сам объект домена НЕ готов, но ваш клиент может проверить его использование интерфейса с помощью макетных объектов.
Интегралы также проверяют несколько реализаций ваших интерфейсов для вашей модели домена. Итак, я не думаю, что это всегда слишком много.
Ответ 12
Я думаю, что основной причиной программирования против интерфейсов является возможность тестирования. Следовательно, для объектов домена - просто придерживайтесь POJO или POС# Os:) и т.д., Т. Е. Просто держите свои классы от добавления какой-либо конкретной структуры, чтобы предотвратить их зависимость от зависимостей сборки и времени выполнения и от всего этого.
Однако создание интерфейсов для DAO - хорошая идея.
Ответ 13
Мы извлекаем интерфейсы из всего лишь потому, что они помогают тестировать (насмехаться) и для таких вещей, как AOP. Eclipse может сделать это автоматически: Refactor- > Extract Interface.
И если вам нужно изменить класс позже, вы можете использовать Refactor- > Pull Up..., чтобы вытащить нужные вам методы на интерфейс.
Ответ 14
* Я делаю это, потому что мне это нужно для создания прокси-объектов моих доменных объектов.
Ответ 15
Это еще одна вещь, о которой я должен помнить, особенно с созданными доменами и объектами DAO. Многие интерфейсы слишком специфичны. Скажите, что у многих объектов домена есть идентификатор и поле статуса, почему они не имеют общий интерфейс? Это вызвало у меня разочарование, ненужную плоскую (наследовательную) модель домена.