#java #spring #interface
#java #весна #интерфейс
Вопрос:
В моем проекте Spring у меня есть много простых сервисов для извлечения данных (просто CRUD). Замысел разработчиков, которые начали этот проект, состоял в том, чтобы создать реализацию для каждого сервиса, подобного
public interface UserService
и затем реализация, подобная
public class UserServiceImpl implements UserService
Поскольку нет никаких шансов, что у UserService
этого будет больше реализации, я действительно устал от этих Impl
суффиксов, и чем больше я читаю (например, эту статью), тем больше я читаю Я понимаю, что у меня есть причины быть больным
На прошлой неделе у меня была дискуссия с другом из команды, и я поделился с ним своими мыслями, но он ответил: «В принципе, вы правы, но Spring любит интерфейсы и работает с ними лучше, чем с классами».
К сожалению, я не эксперт в Spring и, как бы я ни пытался найти некоторые аргументы, я не смог найти ответ, был ли он прав.
Есть ли какие-то веские аргументы в пользу использования такого подхода в Spring, чтобы иметь интерфейс для каждого небольшого класса обслуживания?
Комментарии:
1. Эмпирическое правило: утверждение » нет никаких шансов , что. » X » явно ложно для всех X . Просто говорю … (;->)
Ответ №1:
Я могу сказать по проектам реального мира, что это хорошо работает без интерфейсов, имеющих только класс реализации. Следуя принципу «Вам это не понадобится» (YAGNI), вы упрощаете свой код, если следуете этому правилу. Внедрение зависимостей также хорошо работает с классами, интерфейсы для этого не требуются.
Конечно, вы можете писать и повторно использовать тестовые реализации, но вы можете сделать то же самое с mocks, например, с помощью mockito и перезаписать поведение вашего класса реализации для тестовых случаев.
Ответ №2:
Я просмотрел все ответы здесь, но хотел бы добавить больше о прокси
AOP может использовать прокси JDK или CGlib прокси
Если класс реализовал интерфейс, он будет использовать JDK proxy (предпочтительно, когда у вас есть выбор). Если класс не реализовал интерфейс, он будет использовать CGlib proxy.
Ответ №3:
Это не обязательно и, возможно, основано на мнениях, но вы добавляете интерфейс, чтобы обеспечить будущую гибкость сервиса,
Хотя вы не видите реального использования, это позволит вам использовать другую реализацию конкретных сервисов внутри модульного / интеграционного теста
Вы можете добавить тестовую реализацию вместо текущей реализации и использовать ее вместо реального сервиса при выполнении теста (например, используя другой профиль Spring)
Это можно сделать с помощью mocks, как указывает @Simulant
Ответ №4:
На самом деле не требуется, в настоящее время популярны микросервисы или мини-кодовая база. Итак, обычно в серверной части rest api у вас действительно нет возможности иметь серверную реализацию для определенного интерфейса . В этой ситуации достаточно конкретного класса с @Serivice.
Ответ №5:
Везде, где вы хотите воспользоваться преимуществами шаблона dependecy injection (DI), вам нужно программировать на основе абстракций, обычно интерфейса.
У DI больше преимуществ, но наиболее убедительным кажется то, что он допускает модульное тестирование. Там ваши интерфейсы получат по крайней мере еще одну реализацию (макет реализации), когда вы захотите протестировать свой класс изолированно от его зависимостей (производственных реализаций интерфейсов).
Тем не менее, это не означает, что каждый класс должен реализовывать некоторый интерфейс. Некоторые части кода могут быть тесно связаны друг с другом без проблем.
Обратите внимание, что использование Spring или нет не играет роли в решении использовать DI / не использовать DI.
Ответ №6:
Как предполагали другие, это действительно зависит от вариантов использования. Хотя Spring и Java в целом начинались как подробные языки с дизайном, где интерфейсы должны действовать так, как может видеть клиент, классы реализации, но в наши дни я нахожу все менее подробный код, особенно. с Spring Boot и библиотеками, подобными lombok в наши дни.
Итак, создавать интерфейсы для Service, DAO не обязательно, но это предпочтительнее, если вы работаете над довольно средней базой кода, где есть несколько разработчиков и, возможно, клиентов, использующих эти API и за пределами приложения. Но если вы работаете над небольшими проектами или proof of concept, вы также можете создать CRUD-приложение на одном классе Java.