In his post about Clean Architecture, Robert Martin highlights use cases (or interactors) as one of the elements of application architecture. The purpose of use cases is described as follows:
These use cases orchestrate the flow of data to and from the entities, and direct those entities to use their Critical Business Rules to achieve the goals of the use case.
Not everything is immediately clear from this description, but the main idea can be caught – we get some data and pass it to the domain entities.
And here’s another quote, this time from Eric Evans’ book Domain-Driven Design:
Application Layer: Defines the jobs the software is supposed to do and directs the expressive domain objects to work out problems. The tasks this layer is responsible for are meaningful to the business or necessary for interaction with the application layers of other systems. This layer is kept thin. It does not contain business rules or knowledge, but only coordinates tasks and delegates work to collaborations of domain objects in the next layer down. It does not have state reflecting the business situation, but it can have state that reflects the progress of a task for the user or the program.
This quote is about the Application Layer, which, if you think about it, performs similar functions to the use cases layer. This layer is responsible for coordinating the interaction of domain objects or entities. Indeed, calls to repositories and creation of entities must occur somewhere. In addition, there must be some interaction with external services and systems, accessing which from domain objects is not a good idea, since it violates the principle of purity of the domain model.

So, the application layer (or use cases) receives an external request to perform some action, then passes the request parameters to the domain entities and returns the result of their work in the end. Also, this layer requests entities from the repository, initiates entity state saves, and provides interaction with other services and adapters.
Use Cases vs Application Services
In fact, there are two options for the application layer and use cases:
- Implementing each use case as a separate class (Interactor)
- Implementing a set of use cases as methods of the application’s service class (Application Service)
As you understand, each of these approaches has its own advantages and disadvantages, and I would not like to go into them now. I prefer the second option because it is less verbose and more explicit about your intentions from an OOP point of view, because all you want to do is perform some action, which means calling a method of some class. And besides, you can always make an application service with only one method.