MoviesPreview: the Android app architecture — the Interactor

Juan Peretti
3 min readOct 24, 2019

In the root post of this series, I exposed how the architecture of MoviesPreview is implemented on a high level. In this post, I’ll try to explain how the middle layer of the architecture works — particularly centered in the Interactor layer.

Why an Interactor?

This is the first question that comes into my mind when I think about the Architecture I choose for the application. The first version of the architecture (a very old implementation that can be found in this repo) was based on Clean Architecture, using MVP as the UI architecture and the middle layer was based on UseCases. Something I liked about that implementation is that the middle layer helped me to isolate the UI logic in the Presenter and let the UseCase take care of the business logic.

Or the UseCase was just taking care of accessing the data layer and the Presenter had the business logic? Well, it was kind of both: the business logic was spread in the two layers. The Presenter decided what to show and the UseCase was executing the data adaptations needed to perform an action. It was a complex thing and, most of all was hard to say where the rules were living.

And, to be honest, I always struggled to decide where what was a business rule and what not and what should live in the Presenter and not and what should live in the UseCase and not… A mess.

When I decided to refactor the application and follow the MVVM approach, I first decided to get rid of this middle layer: avoid the UseCase layer and leave the business rules in the ViewModel. But soon I found myself struggling with large ViewModels, with a high number of dependencies (all the Repositories needed to execute an action) and a bunch of logic to query the data layer. So I decided to move that responsibility to a new middle layer that I decided to call Interactor.

The responsibility

The main responsibility of the interactor layer is to group access to all the repositories that are needed to execute an action or to provide a feature in the application.

The ViewModel has only one dependency: the interactor and the interactor has as many dependencies as repositories are needed to execute the action. This simplifies the logic in the ViewModel allowing it to focus on the business rules that are needed to provide the functionality to the user.

On top of that, it facilitates unit testing of the ViewModel by diminishing the number of dependencies that are needed.

An example: Movie Credits

Movie Credits List

To present this feature, the application needs to retrieve the list of characters and crew members that are involved in the credits of a given movie. As an addition, the feature also needs to check for connectivity before executing the data fetch to show the proper UI state when no the device is not connected to internet.

The sequence of events that happen in the repository layer can be simplified with the following diagram:

  • CreditsInteractor is queried to fetch the credits for a given movie.
  • CreditsInteractor checks if the device is connected to a network querying the current connectivity state to the ConnectivityRepository.
  • If the application has connectivity, the CreditsInteractor fetches the credits using the CreditsRepository.

The Reactive approach

The interactor layer follows a reactive approach by exposing LiveData objects to which the client of the layer is subscribed in order to get notified about data updates.

Each interactor declares a series of events that are used to communicate the state of the layer.

--

--