Encapsulating business logic using the Command Pattern
Implementing Use Cases in Swift
What is a Use Case?
By Uncle Bob's definition, a Use Case is basically an Interactor, which is responsible for encapsulating our Business Logic, and should have a well defined intention. But in the real world, it's very common to end up with bloated Interactors, in architectures like VIP/Clean and Viper, for example.
To avoid that kind of problems and really use interactors as a layer for logic integration, we can look back at the Command Pattern and think of a use-case a single command or logic operation.
With that in mind, our UseCase will represent a single operation, with an Input and Output, inspired on the Command Pattern.
Which can be either synchronous or asynchronous, consuming “Core Dependencies” like Networking, Analytics, Services, etc.
Another very interesting path to take is to define domain specific errors, which will kind of translate some Core Dependency error or logic error to a readable and well defined output, that can make your code base easier to understand.
The common case
Refactoring to the Use-Case approach
UseCase examples
Conclusion
This way, we end up with a very well defined operation/command, with a simple API that can bring you a great deal of reusability possibilities.
This technique also fragments your logic into smaller parts, while applying the SoC (Separation of Concerns) concept with a SRP-friendly approach that also simplify your tests.