#Why do we separate ServiceImpl and Service classes?

37 messages · Page 1 of 1 (latest)

deft flint
#

Example:

public interface ExampleService{}

@Repository
public class ExampleServiceImpl implementsExampleService{}

The main reason I found is that the 'xxxService' interface provides structure for all Services inheriting from it.

But I noticed that this duplication of classes gets out of hand quickly.

For example, I might have:

PersonService
PersonServiceImpl
EmployeeService
PersonServiceImpl
ContractEmployeeService
ContractEmployeeServiceImpl
FullTimeEmployeeService
FullTimeEmployeeServiceImpl
PartTimeEmployeeService
PartTimeEmployeeServiceImpl
ListItemService
ListItemServiceImpl
ListService
ListServiceImpl
...

This is just for 7 classes!

What is the point of having so many duplicate and empty classes if the entire point is to implement them anyway?

silent lanceBOT
#

This post has been reserved for your question.

Hey @deft flint! Please use /close or the Close Post button above when you're finished. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

finite fjord
#

Coding by interface makes it so there are a lot less issues if you ever want to mock, decorate, aspect, or generally proxy your services. It works as it is meant to, contrary to trying to do these things on actual classes and having to try-test stuff with their bytecode.

#

That also enables you, if ever useful, to have more than one business implementation of them and to choose which one to use in your app, by config for example

deft flint
# finite fjord Coding by interface makes it so there are a lot less issues if you ever want to ...

I'm not very good at mocking/aspecting/proxying services in general so I feel like I'm not understanding the significance well 😔

Perhaps of the three I'm most familiar with mocking for unit tests, but even then I'm confused as to how having an interface makes it easier to mock

Are there glaring examples which illustrate the advantages of interface coding (particularly for services) which I could perhaps step through to try and understand the reasoning for?

finite fjord
# deft flint I'm not very good at mocking/aspecting/proxying services in general so I feel li...

interfaes makes it easier to mock on the mocking framework, not so much on you.
You may wonder why is it interesting to make it an easier job to a library rather than to you. Said like that, it's not. But if the task is difficult for the library, it may fail to do it, and when it does and you don't understand that it might, then you'll observe results you won't be able to understand.
You can make it so that one doesn't happen by mocking interfaces instead of classes.

deft flint
molten pike
#

as a design principle it helps with decoupling of logic. acts as a mediator and provides the benefits Kyo-chan has given to you.

silent lanceBOT
#

💤 Post marked as dormant

This post has been inactive for over 300 minutes, thus, it has been archived.
If your question was not answered yet, feel free to re-open this post or create a new one.

deft flint
molten pike
#

The ability to switch serviceImpl is very lucrative as a design principle for developer readability/experience

#

Design patterns such as the stairway pattern(Actually C-) which is a mediator allows the ability for example to develop without the external dependency you require

#

if we take an example that you are incorporating an API but that team hasn't delivered their side of the project. You have the api spec and understand the contract between your API and theirs. By indirectly decoupling you are able to actually deliver your entire solution without needing their actual implementation

#

This can be done through creating your Interface/Class(Service/ServiceImpl) and creating ANOTHER Service(ServiceIMpl) acting as a mediator that you are able to MOCK and fully test functionally

#

decoupling your logic affords you this ability - this is a very specific example but being able to disect the code makes its scalable, testable and readable

thorn scaffold
# molten pike decoupling your logic affords you this ability - this is a very specific example...

I've gone back and forth on Interfaces a lot. And I've come to this conclusion.

Don't do it, until you need to.

Single-Implementation Interfaces are a code smell to me. You've decoupled your declaration and your implementation, which is only useful if you have more than one implementation. Otherwise you're just creating more files for the sake of a pattern you're not using.

Interfaces are useful, but until you're actually using them to achieve something for an actual reason, they're useless.

molten pike
#

Thats subjective and an opinion though which isn't widely accepted. Doesn't make it less valid though. I don't think the OP is talking about an interface performing a single use. My point is about decoupling logic as a benefit especially in the example I gave above. At the end of the day abstraction is gained so saying its not being used even in a single implementation use case isn't correct

thorn scaffold
#

Yes that SO outlines the use case of accomplishing a more pattern-based design.

My point is that until you've noticed a pattern, you don't have a need to use it. And don't use something you don't need to.

Otherwise your justification is that "everyone else does", which is a sucky justification. Like anything in programming, I'm going to view the tool, and decide when to use it.

#

Likewise there is a large difference between writing something like framework code, and writing code that consumes frameworks. Those are two different styles. Far too many developers try to write framework style code for code that only needs to consume a framework.

thorn scaffold
molten pike
#

I think your negating your original post which will confuse OP that decoupling logic/code through the use of a service/service implementation is bad practice or a code smell. Your opinion is subjective and decoupling through use of service/service impl is an indirectly inherited benefit and happens as a result of implementing this design pattern

thorn scaffold
molten pike
#

I mean it's not a personal attack to call out what you said is subjective and incorrect. By saying decoupling/abstracting is not a benefit when implementing a service/impl then you are saying implementing it all together is not a benefit which is ludicrous lol. Even if its over engineering it still provides all the benefits explained by Kyo + the main overarching benefit which is abstraction

thorn scaffold
molten pike
#

Also I don't understand your implementing for production and testing at all. Its the same code

thorn scaffold
#
// Service
interface MyService {
  String getDBColumn(String id);
}
// Impl
class MyServiceImpl{
private final PropertyRepository repo;
public String getDBColumn(String id) {
   return repo.getPropertyById(id);
}
// Testing
class MyServiceTestImpl {
   public String getDBColumn(String id) {
      return "FooBar";
  }
}

There would be a basic example where you would have an official testing implementation, and would want an interface to allow for proper object handling.

molten pike
#

Why would you ever do that in absence of mocking?

thorn scaffold
#

I've had to do it once or twice. It was an example of one of the few times I'd consider it a benefit to have an interface for a service.

#

In Developing a Framework, interfaces are incredibly powerful, but consuming, eh.

molten pike
#

You would only need to do something like that if you are trying to implement mocking into a method that has static implications from my experience

#

I do heavily agree with you btw that design patterns should be implemented if necessary. Not just because it's the only one you know lol

deft flint
thorn scaffold
#

Dev work can be split into many Categories.

thorn scaffold
# deft flint I'm really sorry but can you elaborate more on what you mean by/what constitutes...

https://stackoverflow.com/questions/802050/what-is-opinionated-software Opinionated would be another view. If you're using an opinionated tool, you should follow the opinions of the tool. This would be something like using the JPARepository interface over the raw EntityManager in Spring. In unopionated software, you usually have to make some sort of initial system to build off of, kind of like a personal library or framework.

Experience is mostly useful in this context because experience in an opinionated software lets you avoid common pitfalls that might make it harder to test, harder to debug, or even harder to develop. The issue I've normally seen is that schools teach how to deal with unopinionated software, and most junior developers attempt to follow those patterns even in opinionated software.