Использование интерфейсов для написания классов DAO

Я создаю новое веб-приложение, которое будет использовать набор классов объектов доступа к данным (DAO) для выполнения операций CRUD с данными. Я знаю, что должен писать интерфейсы Java, когда у меня есть внешние пользователи / приложения, использующие мои классы DAO. Но если в этом нет необходимости, как вы думаете, мне все же стоит писать интерфейсы? Я буду внедрять классы DAO в классы Spring Controller (я использую Spring MVC), используя spring.


person Srini Kandula    schedule 21.12.2010    source источник


Ответы (6)


ПРИМЕЧАНИЕ, ЧТО: вы всегда должны пытаться отделить интерфейс от реализации. Это даст вам больше контроля над другими слоями, используя этот слой DAO.

Но, как вы знаете, интерфейс дает вам больше абстракции и делает код более гибким и устойчивым к изменениям, потому что вы можете использовать разные реализации одного и того же интерфейса, не меняя его клиента. Тем не менее, если вы не думаете, что ваш код изменится, или (особенно), если вы считаете, что ваша абстракция достаточно хороша, вам не обязательно использовать интерфейсы

Другими словами: интерфейсы хороши, но прежде чем создавать интерфейс для каждого класса, подумайте об этом.

person Vijay Shanker Dubey    schedule 21.12.2010
comment
Если создать интерфейсы для DAO / репозиториев, как бы вы поступили с сущностями? Например, если WidgetDaoImpl (который реализует интерфейс WidgetDao) выполняет операции CRUD с объектами Widget, интерфейсы и сущности находятся в разных модулях (например, api и domain соответственно). Не имеет смысла, чтобы модуль api зависел от домена, так как бы вы это согласовали? Спасибо. - person J. Lin; 30.01.2013

Да, ты должен. Ваши классы, которые их используют, должны полагаться только на интерфейсы. Это позволяет вам легко инициализировать клиентские классы поддельными реализациями ваших DAO, среди прочего, для тестирования этих классов. Если вы просто используете конкретный класс, то клиенты ваших DAO будут напрямую зависеть от этой единственной (доступ к базе данных) реализации, и их будет очень сложно протестировать.

Простота создания классов, полагающихся только на интерфейсы для служб, от которых они зависят, является одной из основных сильных сторон внедрения зависимостей, и вы окажете себе и своему приложению медвежью услугу, не воспользовавшись этим.

person ColinD    schedule 21.12.2010
comment
@ ClinD: вы можете предоставить различные реализации для тестирования без использования интерфейсов. Единственное, что должно быть абстрагировано в интерфейсе, - это важные методы взаимодействия клиентского уровня. - person Vijay Shanker Dubey; 22.12.2010
comment
@Vijay: Я не совсем понимаю, о чем вы там говорите. Если у класса есть зависимость, которая является конкретным классом, лучшее, что можно сделать для обеспечения другой реализации, - это создать подкласс этого класса (если это вообще возможно) и переопределить методы (если это позволяет). Вы все еще можете быть тесно связаны с некоторыми реализациями этого класса. - person ColinD; 22.12.2010
comment
Да, вы правы насчет сильной связи, это будет сильная связь. Но тесная связь - это не всегда ПЛОХО. Уменьшение связи между классами позволит вам по желанию изменять реализации зависимостей. но вы должны заботиться о стоимости производительности и обслуживания. - person Vijay Shanker Dubey; 22.12.2010
comment
@Vijay: Производительность не должна быть фактором при выборе интерфейса для чего-то вообще. Я тоже не понимаю, как это усложнит обслуживание. И я определенно не понимаю, насколько сильная связь с классом, который сам тесно связан с медленным внешним ресурсом, таким как база данных, может быть совсем не плохой. - person ColinD; 22.12.2010
comment
Я лично считаю, что проблема заключается в том, что если вы знаете, что будете тратить много времени на обслуживание, вы можете разрабатывать слабо связанные классы сколько угодно. НО, если, тем не менее, вы не будете так много обслуживать, то слабая связь будет пустой тратой времени. Другими словами, если вы можете гарантировать, что обслуживание не будет проблемой, то крепко соединитесь. Но лично я никогда не мог этого гарантировать. - person Vijay Shanker Dubey; 22.12.2010

Самая большая причина, по которой вы должны писать интерфейсы для своих DAO (репозиториев?), Заключается в том, чтобы вы могли легко создавать макеты (или использовать фреймворк mocking) для модульного тестирования всего, что имеет зависимость от DAO.

Даже если вы не проводите модульное тестирование, рекомендуется следовать DIP.

Кроме того, сколько времени действительно нужно, чтобы "щелкнуть правой кнопкой мыши => извлечь интерфейс" в любой современной среде IDE?

person Brook    schedule 21.12.2010

Я не согласен с Color Blend. В основном мое мнение таково: все, что вводится Spring, должно поддерживаться (и ссылаться) на интерфейс.

person Sean Patrick Floyd    schedule 21.12.2010

Общий подход при разработке API для внешних клиентов - создание интерфейсов, а не классов.

Таким образом, клиент будет знать только о контракте API, который должен быть явно указан в интерфейсе javadocs, и не будет никакой зависимости от выбранных вами деталей реализации.

Кроме того, вы сможете тестировать клиентов вашего API в JUnit, предоставляя имитационные реализации вашего API, что было бы сложнее, если бы вы не использовали интерфейсы.

person Victor Sorokin    schedule 21.12.2010

Я не думаю, что тебе стоит. Вы просто сожжете свое время. Создавайте их, только если это необходимо.

person Tebo    schedule 21.12.2010
comment
@Pangea: Что вы имеете в виду под словом "действительный"? Если вы имеете в виду, что OP может последовать этому предложению, тогда да. Но это не было бы хорошей идеей, особенно с DAO, и в значительной степени лишило бы одного из основных преимуществ использования внедрения зависимостей в первую очередь. - person ColinD; 22.12.2010
comment
У вас тоже есть точка, как у цвета, но не все нужно вводить. - person Aravind Yarram; 22.12.2010
comment
@Pangea: Конечно, не все нужно вводить, и не все должно иметь интерфейс. Но этот вопрос конкретно касается DAO, которые представляют собой типы сервисов, которые следует внедрять и которые обязательно следует размещать за интерфейсами, чтобы остальная часть системы не зависела напрямую от их реализации, базы данных, с которой они общаются, и т. Д. - person ColinD; 22.12.2010
comment
Я немного не согласен. DAO находятся за уровнем сервиса, который координирует оркестровку и трансдемаркацию. Дело в том, что Color Blend также имеет веское значение и не заслуживает отрицательного голосования ;-) - person Aravind Yarram; 22.12.2010
comment
И как один модуль тестировать уровень сервиса изолированно, не зависимо от постоянства? Определив контракт / интерфейс для вашего DAO, вы можете провести модульное тестирование оркестровок, которые уровень сервиса выполняет между сохраняемостью, сопоставителем, сущностями и т. Д. - person Brook; 22.12.2010
comment
@Brook - это субъективно, как и ответ Колора. Все дело в том, что он не заслуживает голоса против ;-) - person Aravind Yarram; 22.12.2010
comment
@Pangea: Заявленная цель SO состоит в том, чтобы программисты-энтузиасты получали ответы. Для меня это означает людей, которые заинтересованы в том, чтобы делать что-то правильно, а не быстро. Не вижу, как на это уходит больше времени, поэтому это плохо конструктивно. - person Brook; 22.12.2010
comment
@Pangea: Я не согласен с вами в том, что должно, а что не должно получать голоса против. Очевидно, есть вопросы, ответ на которые может быть однозначно неправильным, и эти должны получить голоса (независимо от того, сделают они это или нет - это уже другая история). Однако многие практики в программировании нельзя назвать неправильными в абсолютном смысле, но они все равно плохие. Я не хочу, чтобы люди прислушивались к этому совету (который, как бы он ни был задуман, сводится к тому, кому нужны интерфейсы?), Поэтому я собираюсь проголосовать против него. - person ColinD; 22.12.2010
comment
его временные комментарии могут быть неподходящими, но их можно создавать, только если они необходимы. Не злоупотребляйте DI ;-) - person Aravind Yarram; 22.12.2010