androidmvpuse-caseclean-architecture

In clean MVP, who should handle combining interactors?


I've seen good examples of MVP architecture (here and here). Both present only simple interactors, but I wonder how to deal with more complex use case, consisting of steps, which are repeated in other use cases.

For example, my API requires token to authenticate any call. I've created an interactor to get that token (GetToken). I want to get user's last login date (GetLastLoginDate) and then fetch a list of changes that occured between that date and now (GetVersionChanges).

Where those interactor should be chained? I want to keep them separate, because some of them are reused in other parts of the code. I've came up with two solutions.

  1. Presenter should chain all interactors. This solution works as long the use case is not complex and doesn't have many preconditions. It seems to me it's not the right place, because it burdens presenter with another responsibility.

  2. Interactor can use many repositories (no clean architecture rules are broken then). Why not use TokenRepository in other interactors? Because getting token is much more complex than just reaching to repository. Repeating the steps in other interactor does not reuse already existing code.

Both solutions have their flaws and are against basic principles (DRY, single responsibility principle).


Solution

  • If I were you I would just put the logic of getting a token in a separate interactor (maybe named getTokenInteractor) and call that interactor from your others interactor who may need it. That way, it would be in an interactor that you chose either to use a token (and call or not your getTokenInteractor) and also in an interactor that you retrieve it and deal with errors. I would do the same for your getVersionChanges use case and let an interactor chain the calls.

    Let's imagine you have a presenter who needs to display the version changes. He will call a first interactor (GetVersionChangesInteractor) who will first check if he has a token (by calling getTokenInteractor), then call GetLastLoginDateRepository for retrieving the date, and call GetVersionChangesRepository with that date and finally give the result to your presenter.

    That way, your business logic can stay 100% in your interactor and your presenter can focus on how he will display that on screen.

    By the way, if your API needs a token for every call you should move it in an Interceptor so you do not have to deal with it at every call.