Thanks for your comment.The use of the interface here gives a level of abstraction from the class that will implement it.Also it allows for the addition of another implementation to be created.Say UserService2Impl, Spring boot will now have two beans and the @Qualifier annotation can be used to tell which bean should be used.
@Autowired
public UserResource(@Qualifier("userService2Impl") IUserService userService) {
this.userService = userService;
}
This in my opinion allows you to not be tightly coupled and can easily switch implementation details.I agree that for the post you could have used the concrete class and use mockito to mock the methods.However think the level of abstraction was ok for the purpose of the flexibility it adds via the interface and to be able to easily swap out the implementation class via the @Qualifier for future expansion.
Comment hidden by post author - thread only visible in this permalink
On job as freelancer working with Java, JDK17+, Jenkins, Maven, Docker, K3S, Git, In my spare time I'm trying to blog about something useful(?) or try to hack on things I like.
The abstraction from a class which is a service does not make sense because you implement a service with a particular function. So you can use the service directly without the need for an interface. Apart from that having only a @Qualifier will not help here ...it would be easier to use @Service(name="A") and a second implementation which can be simply being used via `@Service(name="B")... the usage of an interface would only make sense if you like to implement a strategy pattern (see dev.to/khmarbaise/spring-boot-stra...) ... with some limitations...
Furthermore you should never start with an interface. Always implement the service directly and introduce an interface only if you really need it...as you wrote for future expansion violates the YAGNI principle which means you aint gonna need it.. means you cant look into the future. Only create an interface if you really need it... Also I would be getting very sceptical if I need a different implementation for the same service? (Design?)...
Switching in implementations you usually don't know upfront.. (if it really would happen).
Apart from that using @Autowired for constructor is superfluous. Also the test class do not need to be public nor the methods because you are using JUnit Jupiter ...
You should reconsider making the whole user controller (UserResource) non public because it is not necessary.
Comment hidden by post author
Some comments have been hidden by the post's author - find out more
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Thanks for your comment.The use of the interface here gives a level of abstraction from the class that will implement it.Also it allows for the addition of another implementation to be created.Say UserService2Impl, Spring boot will now have two beans and the @Qualifier annotation can be used to tell which bean should be used.
@Autowired
public UserResource(@Qualifier("userService2Impl") IUserService userService) {
this.userService = userService;
}
This in my opinion allows you to not be tightly coupled and can easily switch implementation details.I agree that for the post you could have used the concrete class and use mockito to mock the methods.However think the level of abstraction was ok for the purpose of the flexibility it adds via the interface and to be able to easily swap out the implementation class via the @Qualifier for future expansion.
The abstraction from a class which is a service does not make sense because you implement a service with a particular function. So you can use the service directly without the need for an interface. Apart from that having only a
@Qualifier
will not help here ...it would be easier to use@Service(name="A")
and a second implementation which can be simply being used via `@Service(name="B")... the usage of an interface would only make sense if you like to implement a strategy pattern (see dev.to/khmarbaise/spring-boot-stra...) ... with some limitations...Furthermore you should never start with an interface. Always implement the service directly and introduce an interface only if you really need it...as you wrote
for future expansion
violates the YAGNI principle which means you aint gonna need it.. means you can
t look into the future. Only create an interface if you really need it... Also I would be getting very sceptical if I need a different implementation for the same service? (Design?)...Switching in implementations you usually don't know upfront.. (if it really would happen).
Apart from that using
@Autowired
for constructor is superfluous. Also the test class do not need to bepublic
nor the methods because you are using JUnit Jupiter ...You should reconsider making the whole user controller (
UserResource
) non public because it is not necessary.