Reputation: 373
In my Spring project I have many simple services to fetching data (just a simple CRUD). The design of the developers that started this project was to create the implementation for each of the service like
public interface UserService
and then implementation like
public class UserServiceImpl implements UserService
Since there is no chance that UserService
will have more implementation I'm really sick of these Impl
suffix and the more I read (e.g. this article) I'm realising that I have reasons to being sick
I had a discussion with a friend from a team last week and I shared my thoughts with him but what he answered was 'basically you're right but Spring likes interfaces and works with them better than with classes'.
Unfortunately I'm not an expert in Spring and, however I was trying to look for some arguments, I was not able to find an answer was he right.
Are there some strong arguments to use such approach in Spring to have interface for every little service class?
Upvotes: 35
Views: 13913
Reputation: 719661
Do I really need to create interfaces in Spring?
Now clearly, some of the other answers demonstrate that there is (ahem) some disagreement over whether it is necessary. Clearly, this is a matter of opinion ... to some degree. But what about the arguments for and against?
Let's start with what the Spring Documentation says:
Dependency injection
[...]
Code is cleaner with the DI principle, and decoupling is more effective when objects are provided with their dependencies. The object does not look up its dependencies and does not know the location or class of the dependencies. As a result, your classes become easier to test, particularly when the dependencies are on interfaces or abstract base classes, which allow for stub or mock implementations to be used in unit tests.
This is saying two things:
It is implicitly saying that dependencies on non-abstract class will work. So from a purely technical perspective, you do not need to write / use interfaces or abstract classes to use Spring DI. This is borne out by the indisputable fact that it does work with classes.
The authors of the Spring documentation think it is better to use interfaces or abstract classes for dependencies that you intend to inject using Spring DI.
The stated rationale for the authors opinion is that using interface / abstract classes makes it easier to create tests. Specifically, you can much more easily use stub or mock implementations of the beans if you are stubbing / mocking an interface or (to a lesser extent) an abstract class. By contrast, stubbing or mocking final
classes or classes with final
methods can be a problem.
Here's another source that says the same thing:
Now these are clearly opinions, but they are based on the respective authors' experience.
A second rationale for using interfaces is that you may (now or in the future) need to add an alternative bean implementation, and select between the alternatives using DI. And it is often hard to know ahead of time if you will need to do this.
What about the opposing view?
This is rooted on the fact that writing an interface and a single class that implements the interface is redundant. This indisputable.
However:
Also, you may be able to get away with implementing mocks using a mocking framework that side-steps the problem of "no interfaces" by using byte code manipulation.
My take is that the "for" arguments for using interfaces are strong and the "against" arguments are weak ... unless you intend to cut corners on writing your test cases.
Upvotes: 2
Reputation: 399
All about how much flexibility you need. I’d argue that if you’re using something like the strategy design pattern, any service responsible for retrieving data should be an implementation of an interface. But in general, the simpler your design the better.
Upvotes: 0
Reputation: 7
Sometimes you need to use interfaces, sometimes you don't. It depends on the fact that whether or not you might want another implementation of a specific functionality in the future. For example, money-based services should be implemented with interfaces. It is just because you might want to change the implementation of it in the future.
Upvotes: -1
Reputation: 1
If UserService
only has one implement,and use less in other code, use directly class is my choose.When it has more implement or it may hapen in feature,honestly define interface.
Upvotes: -1
Reputation: 1
In my understanding, if it is a multi-person development, first design from the architectural aspect, then abstract definition of the interface, and finally by other technical personnel to implement the business logic of the interface, the interface is meaningful in this scenario. However, if it is a small project with few people involved in the development, this step may not make sense
Upvotes: -2
Reputation: 393
If you are sure that you won't change implementation in future and decision has been made you can use classes without interfaces, main advantage of interface it will give you opportunity of changing implementation details without changing and recompiling business rules code. Let's say that you have OrderService which gets information from external system (XYZ) and data exchange made over HTTP. So you injected XYZService into your Order service, lately for some reason XYZ changed their data exchange protocol to GRPC, in this case if you made XYZService interface and implement it in HTTPXYZService you can easily add new implementation GRPCXYZService and make it @Primary
bean, your OrderService works without recompiling it. On the other hand, if you made XYZService class you have to recompile OrderService whenever you changed XYZService. Another point, OCP (Open Closed Principle in SOLID) says components should be Open for extension and closed for modification, and interface make this perfectly matches this principle while concrete classes usually not suitable for this.
Upvotes: 0
Reputation: 3755
If the interfaces were introduced because of some unforeseen future extendibility, its more likely to be invalid. This is statment has high probability, if the codebase is already mature and the interface still has only one implementation.
If your application is not intended to be extended, then its more likely you can live only with classes. This is applicable for enclosed small applications e.g. microservice. Also as others mentioned, testing can be done without interfaces so testing is not an excuse for having interfaces.
But if you are talking about library or a core functionality that will use/extend by other applications/libraries then its more meaningful to have interfaces. For an example popular android http API client library retrofit has concept of call adapters where different implementation can serve different use cases. This is just an example library which developed with extendibility in mind. If you want to leverage other developers imagination then extendable system with API library (only with interfaces + core models) make more sense. Otherwise its more likely just increase the cognitive overload of developers, this is more likely to be the case for large old codebases.
Once I witnessed an interface with nothing inside of it, laying around 10+ years in the codebase. But it had 10+ implementations. So all boils down to your use case.
Upvotes: 1
Reputation: 596
Maybe I was unlucky but whenever I have seen microservice based on such interface creation I could argue that it was meaningless. From practical point of view interfaces added no benefit what so ever and it only increased bureaucracy. Despite the fact that it not provided any added value there are always some developers which defend interface creation with various arguments. Actually one should consider what benefits it actually brings right here right now and if there aren't any then ask a question why we are doing it.
Upvotes: -2
Reputation: 5622
I've gone through all the Answers here, But would like to add more on proxy
AOP can use JDK proxy OR CGlib proxy
If Class has implemented interface it will use JDK proxy(preferred whenever you have a choice). If Class has not implemented interface it will use CGlib proxy.
Upvotes: 16
Reputation: 20150
I can tell from real world projects, that it works well without interfaces only having the implementing class. Following the principle "You aren't gonna need it" (YAGNI), you simplify your code if you follow that rule. Dependency Injection works also well with classes, interfaces are not a requirement for it.
Sure you can write and reuse test implementations, but you can do the same with mocks e.g. with mockito and overwrite the behavior of your implementation class for test cases.
Upvotes: 26
Reputation: 31
Acutally not needed , currently , micro service or mini code base is popular. So normally , in rest api backend , you really do not have chance to have serveral implemention for certain interface . In this situation , concrete class with @Serivice is enough.
Upvotes: 3
Reputation: 2808
As others have suggested it really depends upon the use cases. Although Spring and Java in general started as a verbose language with design where interfaces are suppose to act as what client, the implementation classes, can see but I am finding less and less verbose code these days esp. with Spring Boot and libraries like lombok these days.
So, it is not mandatory to create interfaces for Service, DAO but it is preferred if you are working on a fairly medium code base where there are multiple developers and possibly clients consuming those APIs outside of the application as well. But if you are working for a small or proof of concept projects, you can create a CRUD application on one Java class as well.
Upvotes: 2
Reputation: 58892
It isn't a must and maybe opinion based, but you are adding interface to enable future flexibility of service,
Although you don't see real usage, it will allow you to use a different implementation of specific services inside unit/integration test
You can add test implementation instead of current implementation and use it instead of real service when executing test (for example by using different Spring profile)
This can be done using mocks as @Simulant points out
Upvotes: 4
Reputation: 1239
Wherever you want to reap benefits of dependecy injection (DI) pattern you need to program against abstractions, usually an interface.
There are more benefits to DI, but the most persuasive seems to be it allows unit testing. There your interfaces will get at least one more implementation (the mock implementantion), when you will want to test your class in isolation from its dependencies (those production implementations of the interfaces).
That said, that doesn't mean every class must implement some interface. Some parts of code can be tightly coupled together without problem.
Note that using Spring or not doesn't play role in the use DI/not use DI decision.
Upvotes: 1