In clean MVP, who should handle combining interactors? - android

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.
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.
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).

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.

It's possible that the MVPC pattern is what you're after. This is something I wrote ages ago on it (though the code example is pretty poor so please excuse that!)

Related

Repository can be singleton in mvvm android?

I don't understand few things about repository in mvvm, also have seen multiple blogs and code templates. Every one of them doesn't match with other. So
Why there is needs to have multiple Repositories classes? Why single repository shouldn't handle all the data IN OUT for the app?
Why Repository shouldn't be a SINGLETON class in project?
What a repository('s method) should provide to viewmodel Result(Sealed class) or actual response from a api like list(or error)?
SharedPrefrences should be handled by Repository as well or not? if no why
I believe Repository should be that part of your code which should process all the data from multiple source whether be database or network or sharedprefs. So what do you think?
Purpose of repository is not only to manage requests/response but also provide a layer to keep responsibilities separated. If you have 2 modules (let's say Login and Registration), it is much better to keep repositories separated to keep things clean and simple rather than having a single repo with spaghetti code.
This point is opinionated. IMO you can have singleton repositories because they are stateless i.e they do not hold any kind of data which may cause conflict between multiple ViewModels/Modules.
Depends on you but it is much better to return Result. With Result you can handle Success Failure and Error Messages easily and return different Error Messages directly from repository rather than deciding in ViewModel what message to show. Messages can be either from server or internal exception messages.
SharedPreferences is a datasource. Yes you can manage preferences using repository pattern.

Can a use case be called in data layer in context of Clean Architecture?

I have read a couple articles about clean architecture concepts here and here and others.
I think I understand what is going on but they didn't solve the question that I have.
I wonder if a use case can be called from data layer. if so, how? if not why?
UPDATE:
what I am trying to do is to track what is happening during each usecase with a event usecase. Sometimes, I need to collect those info in data layer as well.
Let's say I have
CollectEventUseCase
for that event usecase. I want to track if a person data lookup from network was fail but successful from database during the LookupPersonUsecase and I want to collect that information that lookup was failed from network but successful from database, is this a bad idea to call CollectEventUseCase in data layer? is this okay solution to this case? or whatelse should be the right approach?
Short Answer - No, in a CLEAN architecture the data layer should not be calling through to a use case as it would be breaking the separation of concerns. Data layer should only be concerned with data, not business logic which lives in a use case.
Long Answer
One main reason for implementing a CLEAN architecture is for implementing separation of concerns, meaning each layer addresses a specific concern in your app. Expanding on the photo in domain layer Android documentation, an app architecture might look like the picture below.
Where the domain layer would contain all of the business logic for presentation and use cases which can communicate with different sources in the data layer.
The data layer exists to serve as an abstraction over where data is coming from and that should be its only responsibility. Most apps data layers are fetching data from the network and then caching that data in a local database. So to best separate the concerns, a use case should only be concerned about interacting with different sources from the data layer and any business logic.

Clean Architecture: Where to implement pagination logic?

There is a REST API where search keyword entered by the user is used to query and get results. Sometimes, too many results are returned. I don't want to put a maximum result limit on the server side so I want to handle it on the application. In the application, I try to follow Clean Architecture. I have a fragment, a presenter, a usecase and an API client. User enters a keyword, presses search button, the keyword passed to related usecase function through presenter. Usecase gets results from API client and pass results to presenter through listener. Presenter notifies fragment so that results are displayed.
I want to show max of ten pages of results. Where should I put this control? Usecase or presenter?
If you will strictly make it ten pages ALWAYS, put it on your usecase because here, application business rules resides. So you don't need to pass it if your just always going to pass ten.
But, I suggest to make it as a parameter on the presenter, to make it flexible because maybe you will have a scenario in which you want to adjust the max pages on a specific activity/fragment.
Is pagination part of your domain? If it’s not, you might want to have a separate query interface/flow. Use the domain repository for write based operations. Load the entity, update, save. For queries have a different interface that enables query and filter operations. The user case still exists. The input still has the parameter, but your domain repository api is clean. You can even have the same database class implement your query api.

Android MVP with RxAndroid + Retrofit

Recently I started reading a lot about MVP and I want to get into practicing my projects with it.
However I am not able to correctly understand where should Rx + Retrofit code go? I think it should be in Model Layer via Interactors but still can someone share some light on this?
Also what happens with the RX callback? the onNext(), onCompleted() and onFailure() passes data back to Presenter or do we implement listeners and then pass it on to Presenter?
I also want to persist data (Realm/StorIO) when I get it in onNext(), So again pass it to another DataLayer or where should it Go?
Also should we decouple Rx callbacks further?
I am following this post
https://davidguerrerodiaz.wordpress.com/2015/10/13/a-brief-introduction-to-a-cleaner-android-architecture-the-mvp-pattern/
and this seperate github repo from antonioleiva.com
https://github.com/antoniolg/androidmvp
As you pointed the RxJava functionality defines a use case of your model layer so it would be placed in an interactor of this layer. You can create a different interactor for each use case. Let's say you are pulling a list of users from your server, this would be a use case and an interactor that will have the RxJava/Retrofit Observable.
Then you will have a Presenter with an Observer in it which is interested in this users list, so it will be subscribed to that Observable.
And finally when this Observer in has all the data from the Observable (onCompleted), it will transform this data (if needed it) and pass to the View which will be just in charge of display it.
There is awesome post explaining mvp.
Rx is just additional tool for it.
http://hannesdorfmann.com/android/mosby-playbook/
there is deep explanation and source code with example.

Android - Organizing Login fragment and MVC principles

By following basic tutorials I've created a login fragment that has a username textview, password textview, and button. It POSTS the login info to an API which validates the login. EVERYTHING i do is in the login fragment (controller).
I have 3 questions:
Following Model, View, Controller - I do not have a model. The View is the layout, and the controller is the fragment. Is this right?
I feel as if the login code should be broken down into more classes... such as separating out the post request from the rest of the code. If I were to move the asynchronous request to another class file, I would also have to pass the views needing to be hidden while attempting to validate the user. Is there a better way to accomplish this, or is it OK to leave the http request code in the login fragment?
Is there something I'm missing that might need to be in another class?
In my opinion, in Android you don't have typical MVC pattern like in some web applications. You can treat XML layouts as a views. It's provided by design of the Android API. Activity is the actual controller. If you have some complicated logic you can create separate classes, which will be responsible for that logic. Activity shouldn't be of course "God class" holding all the operations. You can store your models in a separate package as a POJO objects and access them via other classes responsible for logic of the application. You shouldn't keep HTTP requests in Activity or Fragment. You should move them to another class to separate logic responsible for displaying data from logic responsible for retrieving data. Fragments should be used only when it's necessary, but not all the time. You can use them, when you want to display dialog, use tabs in your layout or create adaptive layout for tablets and mobile phones. I think, if you don't really need fragments, you don't have to use them. You can read how Square is advocating against Android Fragments. You can deal with asynchronous requests with RxJava. You can return Observables and subscribe them every time you want to create asynchronous request. It gives you good granulation, separation and control over your code.
Of course, it's only my opinion based on some experiences and I may be wrong. I'm eager to hear opinion of other developers and their experiences.

Categories

Resources