In 'clean architecture' the interactors (use cases) are responsible for defining busines logic. Most of the examples define use cases in such a way:
public MyUseCase() {
public boolean execute(...) {
int id = repository.insert(a)
if(id > 0) {
b.aId= id;
repository.insert(b);
...
}
}
}
Interactors use mostly simple CRUD like operations or queries on repository. The above example is synchronous for the case of simplicity but you can find repos with the same approach using asynchronous solutions like callbacks or rxjava.
But what about use case inegrity. For instance, you can't be 100% sure that after inserting a
it will still be there when you insert b
.
What if after inserting a
you get some RepositoryException while inserting b
.
All the repos I've seen so far don't take it into account, so my question is:
What's the solution of the above problem in clean architecture?
An important goal of clean architecture is to provide developers with a way to organize code in such a way that it encapsulates the business logic but keeps it separate from the delivery mechanism. The main rule of clean architecture is that code dependencies can only move from the outer levels inward.
The adapters are the Interface Adapters from the Clean Architecture diagram. All incoming calls from Business Logic get converted into a format that the mechanisms can understand. For example, our Business Logic makes a call—against an interface—to save a Customer.
This answer may be kinda late, but I have struggled with the same problem and came to a conclusion that transaction management is, in fact, part of a Use Case - like, "If something goes wrong with B, revert A's state". So, it can and should be explicitly stated within your UseCase, probably with some kind of "DataManagerRepo", like this:
public MyUseCase() {
public boolean execute(...) {
dataManagerRepository.openTransaction()
try {
int id = repository.insert(a)
if(id > 0) {
b.aId= id;
repository.insert(b);
...
}
catch (MyException exc) {
dataManagerRepository.rollbackTransaction()
}
dataManagerRepository.commitTransaction()
}
}
Names may vary to abstract away integrity mechanism, but the idea is the same. I hope this will help somebody.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With