This repository was archived by the owner on May 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 108
Review abstraction levels of services #61
Copy link
Copy link
Open
Labels
enhancementNew feature or requestNew feature or requestin reviewModerators are investigating how to best proceed with the issueModerators are investigating how to best proceed with the issue
Description
Current Implementation
The services currently expose a mixture of abstraction levels in their APIs that provide an incoherent set of operations and lead to a fractured programming model. Take the TAN redemption use case for example. The programming model currently looks as follows:
- A controller loads an instance of the aggregate.
- There are some business checks applied.
- If they succeed, state is manipulated by calling some setters.
- The state is persisted by calling
save(…)
.
That's a very low level interaction model and it's error prone fro a couple of reasons:
- You can accidentally forget one of the steps and might not actually realize this. Ideally a business operation consists of exactly one call to some service that either fails or succeeds.
- State is manipulated through setters. I.e. we're poking on individual fields. It's the responsibility of the calling code to make sure that the right setters are called, potentially in the right order. Also, as the setters are public, any code can actually call them.
Suggested Enhancement
- Revisit all methods that call
save(…)
on the service, look for which state transitions they apply to the entity beforehand and turn those use cases into service methods. All code that does not need any references to other Spring beans could go into entities ("If you need to call two setters in a row you're missing a method."). - In combination with Avoid layer packages #60, setters could be made package protected, so that the web code is unable to call those individually but is forced to go through the service by the compiler.
Expected Benefits
- Reduces the amount of ceremony to be implemented in controllers to realize a use case.
- A clear separation of code that is strict (services, entities, etc.) and prevents any kind of misuse through the help of the compiler or by rejecting invalid state. This can then be separated by code that needs to be "forgiving", i.e. also accept invalid data by clients in the first place to produce proper results (usually though some kind of validation).
Again, happy to provide a POC for this in a PR.
sventuerpe and majoko87
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestin reviewModerators are investigating how to best proceed with the issueModerators are investigating how to best proceed with the issue