4

Hi there Spring/SpringBoot fans/experts,

Hope you’re doing well. I’ve been grappling with this question for a while now, and I thought I’d ask a spring/springboot expert for their opinion and experience on it. It’s about interface as it relates to its usage in springboot.

First of all let me say this; from a Java or software engineering stand point, I understand and am well aware of the use or purpose of interfaces, they are contracts.

So, from springboot as a FRAMEWORK/library standpoint, it make sense in the framework source code.

Now, from springboot as an APPLICATION I’ve seen cases where every service class (@Service) has a corresponding interface :

public interface MyService {} 
public class MyServiceImpl implement MyService {}

99.99% of the time, these interfaces never get implemented by anything else ever. Why has this become such a popular thing to do in springboot, where every single service class has a corresponding interface even though nothing else will ever implement these interfaces?

To me it seems to create more complexity and code to maintain with no apparent benefits. Note that I’m strictly referring to @Service class interfaces only.

Is it good practice to do that? Is there something I’m missing here. What’s your experience and thoughts on this please?

Thank you in advance!

b.s
  • 2,409
  • 2
  • 16
  • 26
  • related: [Should every class implement an interface?](https://stackoverflow.com/q/2659366/1371329) – jaco0646 Sep 15 '21 at 00:22
  • Emmanuel, welcome to SO. I think it is a matter of design vs implementation. Someone who is reading the line: `@Autowired MyService myService;` in a class may just need to know the contract of `myService` to see what role it plays. But some other readers may need to know whole implementation `MyServiceImpl` (for example, to know how you implemented the whole thing and how it can be tested). There are other reasons as well, for example you can autowire a different implementation (or mock it ) in testing or you can dynamically use a different implementation based on profile or `@Condition*`. – Ritesh Sep 15 '21 at 01:53

2 Answers2

8

This pattern was indeed used quite a bit in quite some tutorials and online resources but I'd argue it's quite outdated. Back in the XML days, you didn't have such a thing as a configuration class so the main way of configuring a bean was an XML entry, with public setters for the collaborators. As you didn't want to expose that in your API, having an interface that declares your public API and the implementation taking care of it made sense.

With modern Spring, this view of the world is totally outdated and there's certainly not a strong desire on our side for such a paradigm. Constructor injection is the norm now, and with that, the separation between an interface and its sole implementation is not very useful.

One could argue that they don't want any Spring annotations to surface on public APIs so this as still a use. That said, if you use construction injection and explicit bean registration, you don't need any annotations for dependency injection. If you're feeling strongly about this and use additional aspects such as transaction or caching, then yes you'll have to create an interface if you want to hide those annotations from your public API.

Stephane Nicoll
  • 31,977
  • 9
  • 97
  • 89
  • Please read the Spring creator Rod Johnson's book "J2EE Design and Development" where he wrote pn page 114: "OO design is more important than any particular implementation technology (such as J2EE, or even Java). Good programming practices and sound OO design underpin good J2EE applications. Bad Java code is bad J2EE code." @Stephen, to new developers please recommend 'good prommaing practices, good OO practices, and good spring practices' in that order. Rod said EJB was not greater than OO and same can be said for Spring. It is not an outdated view. – Ritesh Sep 19 '21 at 18:12
  • See [Chapter4] (https://media.techtarget.com/tss/static/articles/content/RodJohnsonInterview/JohnsonChapter4.pdf) – Ritesh Sep 19 '21 at 18:12
  • 2
    @ritesh, I don't really see where you've seen that not having an interface for a single implementation of a contract is a bad practice. The question was whether Spring was enforcing that in any way and the answer is no. – Stephane Nicoll Sep 20 '21 at 14:47
  • I have never seen an exception of the guideline which says that dependencies should be based on abstractions not the implementations (same book page 115). Even if it is a single implementation at the time of design, we never know how the application would change in next few years. You should make it clear (especially to new developers) in your reply what Sping enforces or not rather than saying "With modern Spring, this view of the world is totally outdated....". – Ritesh Sep 20 '21 at 23:01
  • 2
    I was referring to using an interface + an implementation to hide setter injections. That said, I am not going to update my answer as I disagree with you that requiring an interface necessarily means sound OO design. – Stephane Nicoll Sep 21 '21 at 05:54
  • @Ritesh Your comment **"Even if it is a single implementation at the time of design, we never know how the application would change in next few years."** is a direct violation of the [YAGNI](https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it) principle. More importantly, it's just bad practice beyond just the interface topic at hand. – Emmanuel Piard Sep 22 '21 at 00:37
  • @EmmanuelPiard ok, I see your point. – Ritesh Sep 22 '21 at 14:12
  • @EmannuelPiard, A question though: Suppose there is a single implementation, as Stephen describes, but that single implemenation is injected into multiple other classes (let's say 20 other classes) through constructor, would you still not create an interface for it because it would violate YAGNI? – Ritesh Sep 24 '21 at 04:12
0

In spring, @Service is usually responsible for specific business logic, and business code usually contains a lot of changes. So it is generally implemented using interfaces. I don't quite understand why your business code is always empty.

yao Mr
  • 26
  • 2