5

Используя фреймворки Spring, принято для создания сервиса создать интерфейс определяющий основные методы сервиса.

interface MultiplicationService {
    long execute(int a, int b);
}

class MultiplicationServiceImpl implements MultiplicationService { // implementation }

В чём смысл создания интерфейса?

  • один из вариантов - легкость тестирования(возможность замокать) – ermak0ff Aug 09 '21 at 14:41
  • 1
    @RomanC Ссылка плохая. – Mikhail Murugov Aug 09 '21 at 17:12
  • @МихаилМуругов В смысле что значит плохая? – Roman C Aug 09 '21 at 17:29
  • @RomanC Битая. Вы пробовали её открывать? – Mikhail Murugov Aug 09 '21 at 17:43
  • Это принято не только в Spring и не только для сервисов. Нужно это для того, чтобы можно было легко поменять одну реализацию на другую не изменяя логики класса или метода, который использует объект реализующий этот интерфейс. Как следствие это облегчает тестирование (легко заменить объект моком) да и вообще модульную разработку (модуль использующий интерфейс не обязан видеть модуль с реализацией). – Gleb Kuznetsov Aug 10 '21 at 06:49
  • @МихаилМургов Попробуйте вот эту ссылку. – Roman C Aug 10 '21 at 12:39

3 Answers3

1

Если имплементация сервиса одна и только одна и в будущем не планируется других реализаций, то можно и не париться по поводу интерфейса.

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

Более глубокое копание в этом направлении можно почитать тут.

По этому многие просто используют правило - не хочешь неожиданностей в будущем - делай интерфейс :)

1

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

MxWild
  • 441
-1

Во-первых, как заметили в чате, это упращает тестирование. Меньшая связность позволяет легко поменять реализацию.

А во-вторых, в спринге можно инжектить бины по интерфейсу так же, как и обычные pojo классы (но требуется, чтобы спринг мог однозначно определить какой бин следует инжектить, иначе - кинет исключение). В этом плане смысл такой же как и в java core.

Sergey Zh.
  • 1,311
  • Можно и без интерфейса, никакого смысла с Java core. – Roman C Aug 10 '21 at 12:42
  • Зачем "инжектить бины по интерфейсу так же, как и обычные pojo классы". Что такое pojo классы, и зачем им интерфейс? – Roman C Aug 11 '21 at 17:07
  • @RomanC про pojo https://ru.wikipedia.org/wiki/POJO#:~:text=POJO%20(англ.%20Plain%20Old%20Java,тех%2C%20которые%20нужны%20для%20бизнес-модели – Sergey Zh. Aug 11 '21 at 18:11
  • @RomanC если есть иерархия классов и наверху интерфейс, то удобно инжектить по нему, смысл этого довольно близок к полиморфизму обычных (pojo) классов – Sergey Zh. Aug 11 '21 at 18:14
  • про pojo там вообще ничего не написано, приведи мне примеры pojo и не pojo и объясни в чем разница. Что касается иерархии классов то тут pojo как бы сомнительно называть, тем более то, что касается полиморфизма, то pojo вообще не при чем. Про полиморфизм можно почитать тут. – Roman C Aug 11 '21 at 20:13
  • @RomanC термин pojo вообще Мартин Фаулер придумал, это неофициальное слово, но его многие используют. Любой Спринг бин - это НЕ pojo. А вот классы моделей (которые не спринг бины) - это pojo. – Sergey Zh. Aug 11 '21 at 21:48
  • Почему "спрнг бин это НЕ pojo"? А вот например Struts акшен Бин это pojo? Вы сказали, что можете иньектить pojo даже если они не являются спринг бинами "в спринге можно инжектить бины по интерфейсу так же, как и обычные pojo". А вот классы моделей, каких моделей? Перзистенс, сервис, вью, акшен модели? Сущности хибернета тоже pojo? Что-то у вас совсем непонятно. Приведите мне хоть одно определение pojo. – Roman C Aug 12 '21 at 09:35
  • @RomanC я видимо не точно выразился, pojo не нужно инъектить. Я имел ввиду, что смысл интерфейсов у бинов, такой же, как и у pojo классов - интерфейс позволяет заинъектить любой класс его реализующий. – Sergey Zh. Aug 12 '21 at 09:56
  • Выражаться нужно правильно, смысл интерфейсов совсем другой. Вот здесь я более точно описал смысл. Интерфейс ничего не позволяет, "заиньектить любой класс" тоже не получится, интерфейс это абстрактный тип, более подробно об этом можно почитать здесь. – Roman C Aug 12 '21 at 10:32