I have a couple activities, while each of them is rather unique, there has to be some common api calls like getCurrentUser() or updateUser()
Given the MVP pattern (I am currently using MVP mosby), since each of these activity only has a single presenter. As i am developing, it seems that sometimes I copy-paste a lot of these common api calls all over these presenters. Say I have api Call A, B, C, D.
A, C are used in presenter 1,
B, D, A are used in presenter 2,
C, E are used in presenter 3
.....
and so on. It is really difficult to find a "common" presenter to inherit from. So the api calls, C and A are basically copy pasted.
My question is, given the current situation, what is the best way to avoid code copy-pasting? Is it almost not avoidable? Or should I try my best to do OOP but risking a bunch of refactoring every time API calls are added/removed from different presenters?
Interactor pattern (use case pattern) can solve your current issue of duplicating code.
The idea is that you extract all logic behind getCurrentUser() and updateUser() methods into a class (interactor) and use this interactor inside multiple presenters.
This is a very simplified explanation. I suggest you do more research starting with this post and this post for example.
You should decouple your common API and presenter code by putting all the API calls inside one or multiple Java classes that can be referenced from any presenter.
Therefore.
ServiceA exists (A Java Class).
ServiceA performs API calls A,B,C,D.
Service A can be called from Presenter1, Presenter2, PresenterN, PresenterN+1.
It should not matter what the presenter is.
If you want to restrict certain Presenters from having access to different API calls. Then this is when you should consider having ServiceA, ServiceB, ServiceC. Where ServiceA can only make API call A and D, Service B and Service C behave similarly.
Decoupling your Presenter code and common(Web Service, internal API, w/e code) will allow you to scale without having to do copy and paste.
Good luck.
I think you are risking more refactoring if you don't do it the OOP style, with inheritance.
Let's say you want to modify the way you handle some api call. If you are copying code, you'll have to refactor everywhere you copied the code in the first place. If you inherit from a common presenter, you can just modify once.
You should make interface for your API that contains all your API requests. Then make singleton class that execute these requests, and you can easily access this class from your presenters.
Now you will still have some duplication and you will need to call this singleton multiple times in presenter and handle response in each of them, but that's what you need to do. Every presenter should be able to handle response different way, so you can't just pack them as one (even they will usually handle it the same way - by passing data to view).
If you think that you are writing a lot of similar code that does nothing, well that what you get with MVP. You also get great testing ability, easier refactoring and easy mock of requests - you could swap your real singleton for mock that implements same interface and everything works.
Related
I am using Kotlin Corountines with MVVM pattern and faced a problem: The data processing part is being done inside the ViewModel. While the repository seems not really necessary. When the application needs to call many APIs, the ViewModel will swell. What is everyone's solution to this problem? Thank you
The repository is needed, because in the case when you have a large app and gave too much responsibility to the ViewModel it's broke the separation of concerns principle.
Basically in the Andorids Guide to app architecture :
A first idea for implementing the ViewModel might involve directly
calling the Webservice to fetch the data and assign this data to our
LiveData object. This design works, but by using it, our app becomes
more and more difficult to maintain as it grows. It gives too much
responsibility to the UserProfileViewModel class, which violates the
separation of concerns principle. Additionally, the scope of a
ViewModel is tied to an Activity or Fragment lifecycle, which means
that the data from the Webservice is lost when the associated UI
object's lifecycle ends. This behavior creates an undesirable user
experience.
Instead, our ViewModel delegates the data-fetching process to a new
module, a repository.
And direct answer for your question:
Even though the repository module looks unnecessary, it serves an
important purpose: it abstracts the data sources from the rest of the
app. Now, our UserProfileViewModel doesn't know how the data is
fetched, so we can provide the view model with data obtained from
several different data-fetching implementations.
Basically, you can give all work to your ViewModel, but it's not recommended.
If you work/planning to work as a dev, maintaining your code, make it flexible to change and understandable for others is also important and usually, everyone appreciates this
I am developing an Android app that does Human Activity Recognition.
It basically works like that - Service constantly reads the accelerator data and stores the recognized activity (i.e. Walking, running) in a database. The user can see all of the recognized activities in an ListView in activity (accesses the database). Every User table in the database has a pa_goal (physical activity goal) field which the Service reads from the database and does some checks.
The user, of course, can change this goal from an activity. Since I will be implementing the MVP architectural pattern.
I am unsure where to put the Service? It surely isn't View. Any advice?
In a clean architecture, which is what I am assuming you are using MVP for, there is the idea of separating the framework from the business logic. This is essentially what a normal presenter allows you to do.
In this case its not a view you are dealing with but the principle is similar. You don't want all your business or application logic mixed in the Android code when you can separate them out for nicer, more single responsibility classes. So I would say that while it isn't a view you should still have a presenter type class (probably better to be called controller or manager maybe).
This class would be a POJO that controls how your service behaves which is easily testable with standard junit tests and service mocks. This class and the service could then be put into its own feature package and interact with the back end models the same way as your presenters.
So, in summary, the role is of another feature of your app that sites alongside the other features (which are usually just views in my experience).
Hope that helps
This article helped me in a similar situation, although may not be exactly yours, the idea is the same:
https://android.jlelse.eu/android-bound-services-and-mvp-12ca9f70c7c7
Basically, the author works around the fact that a bound service is tightly coupled to an activity, and it adds extra lifecycle calls to it.
I am in the same situation. Finally I decided to do something like this:
Activities or Fragments are out of scope, they do not know anything about MVP BUT i am going to use an event bus like Otto to send signals/events, So:
My classes which extends some kind of Presenter know nothing about Android Context but they will have an MvpView interface, with only onAttachPresenter and onDetachPresenter.
The class which extends Service will have a Presenter attribute and implements some MvpView interface with onSucess, onError, onStart, onComplete or something like that and same events for Otto (onSucessEvent, onErrorEvent, onStartEvent, onCompleteEvent).
So when I need to do something the Activity or Fragment will start the service, the service will "start" or talk with the Presenter and when the presenter finish with success will call to mvpView.onSuccess() and store the info inside a local DB with SQLite (storeIO maybe) and finally the Service will invoke Otto and pass the signal (without any data on it), probably onComplete.
Finally the signal will be catched by my UI (fragment maybe) and retrieve all the info inside a DB in SQLite.
So when the onSucess happens the UI will show the latest and best data BUT when onError happens will (at least) show some info (or not if you want) saying to the user "there was a problem but at least you can see something", bot onSuccess and onError will call onComplete after all.
Do not know if this is the best solution but in this case I think I am not going to deal with Activities or Fragments lifecycle and do not care about onSaveInstance and restore data when the user rotates the device. It will always fetch the latest data inside DB, and if something happens (no internet connection) you can at least show something when you receive the onComplete Signal.
Some facts I am still thinking:
The Presenter won't be a singleton class
Presenter knows nothing about Context but yes with MyApplication class
What happens if for one screen (Fragment) you have differents service with differents onSuccessEvents? Simply use some kind of action as an ID, to identify them.
Never make the Activity Fragment implements the MvpView, you will have to deal with the lifecycle.
I'm very new to MVP and can't seem to grasp this concept.
Basically I have an activity which has an onClick which displays a DialogFragment. The activity does what it needs to do with MVP. The DialogFragment does too. However they are fully independent with regards to linking to each other which is posing a problem for me. When the DialogFragment chain is finished doing what it needs to do, the presenter on this layer holds the data to update the view on the Activity layer. I want the presenter in the DialogFragment layer to give the data to the presenter in the Activity layer who can easily let their view know as it's already linked up nicely.
I've thought of interfaces, read about eventBus (I know nothing about this so be kind).
There must be a specific way of achieving this because it must be a common task, I know I'm going to be doing it a few times in this application.
Your model is the data source in MVP.
Don't know if I got your case properly or not but the model is responsible for providing data to the presenters.
So generally, your other presenter should be accessing the data it needs from the model. Your first presenter can ask the model to do insertions or updations etc required as per the business logic.
Once the alterations have been done by the model, your second presenter can access the data by asking for it from the model.
Hope, I made that out clearly.
As per clean architecture, design Interactor is part which contains all business logic. The term Interactor is quite confusing to me. Interactor seems to me like interacting between two different layers like data and presenter.
Is it the right term to use?
Can anyone please clear the purpose of Interactor? Which pattern does it follow?
If Interactor is not what it seems to me then what is the design pattern for
layer-layer interaction?
An Interactor is a design pattern that has nothing to do with "business logic" concept. Without going in deeper level of detail the Interactor pattern is an extension of the Command pattern; Each "business logic" object is treated as a "black box", a simple instruction to be executed for the client, decoupling the object that invokes the operation from the one that knows how to perform it. (refer to the bibliography for extended explanation).
In the android enviroment there is a simple 'rule' that demands to the programmer to do long time consuming task in a background thread, so the interactor patterns extends the "Command pattern" adding a layer of threading. All this complex stuff is implemented to create a "clean architecture" which entails a code that is scalable, maintainable and (arguably) understandable.
About the question .. ¿what is the design pattern for layer-layer interaction? It could have more than one rigth answer, depends of the situation. You could use a simple Interface as the entry point, so you could use the Adapter pattern, or maybe the Facade pattern, or if you want to do something more advanced you could implement an eventbus system.
Source:
Design patterns explained simply - auth Alexander Shvets. page 14 (Adapter), page 32 (Command), page 47 (Facade)
In the clean architecture approach, the Use Case Interactor is a layer that express the specific business rules. The Use Case Interactor interacts with the Entities (agnostic business rules) to achieve the Use Case intention. Entities can be used in another applications, once they are agnostics, on the other hand, the Use Case Interactors are specific application objects.
Can be found in the Clean Architecture book by Robert C. Martin at chapter 20
If you're familiar with domain driven design, then an Interactor can be compared to an Application Service. Also, it is incorrect to say "As per clean architecture, design Interactor is part which contains all business logic." On the contrary, Entities would contain the business (application-agnostic) logic; whereas Interactors would contain the application-specific logic. The Interactors would call the Entities to fulfill a use case, where a use case might be something like Create Purchase Order.
Going back to using Clean Architecture terms that Robert Martin (Uncle Bob) uses in his training video Architecture, Use Cases, and High Level Design, Uncle Bob says the following:
Interactors are application-specific. That means that any application specific business rule belongs inside an interactor. The interactors achieve their goals with application-specific logic that calls the application-agnostic logic within the entities. For example, the CreateOrderInteractor invokes both the constructor and the GetId method of the OrderEntity. Clearly, these two methods are application-agnostic. It's the interactor that knows how to call those two methods to achieve the goal of the use case.
For your observation that the Interactor seems like it is interacting between two different layers like data and presenter, that job actually belongs to the Boundary. The Boundary sits between the delivery mechanism and the Interactor, where the delivery mechanism might be a desktop application, MVC app, API, etc. This keeps the actual application and business code separate and transferable from one delivery mechanism to another.
He also has a nice diagram in the Extras section showing the interaction if you purchase the video. It looks something like the following:
Delivery Mechanism ==> Boundary ==> Interactor ==> Entity
P.S. The video referenced above is highly entertaining and informational.
From what I'm reading, it's the equivalent of the Presenter in the Model View Presenter (MVP) architecture.
It does business logic, not store or display data. It create a separate layer independent of how or where data is stored or displayed. It only cares about inputs and outputs in any format. It could be used in a combination of the Observer, Adapter, and Façade patterns to be an interface for callbacks, a generic extension point of the code, and a decoupled entry point for any non UI or data-storage usage, respectively.
I assume it is called an Interactor because the View interacts with it to calculate values and refresh any displayed UI elements and it interacts with the Model objects to extract data. It could also interact with a database for CRUD operations, but I think that's mostly addressed in the Repository Pattern as that isn't really business logic.
Interactors provides implementations for various use cases. Ideally, there should be one interactor per use case but it may differ according to the scale of your application.
Now, why it doesn't make sense for every application? Imagine you have two applications. In the first app, you just need to read a user. In the other application, you just update the very same user. You would have two different interactors like GetUserInteractor and UpdateUserInteractor. If you think about it, UpdateUserInteractor would make no sense for the first application (and vice versa), right? But your business/domain logic for both applications can still be the same where the implementations of both services (read and update) are included, for example, in the regarding business/domain object (or as separate use-case objects). These objects obviously encapsulate application agnostic business rules as they can be plugged under two or more different applications.
The communication takes place between the app and users is often application-specific. As others already mentioned, you can have your interactors execute commands on user actions. Or you can go for another similar way. But the command pattern is really convenient and arguably make the whole code more consistent, uniform, and easy to understand.
Last but not least, the other important aspect of interactors are 'boundary interfaces' which are the classes that polymorphically deployed for both input and output delivery.
(PS: For example, in Android, with the new architecture components, Fragment/Activity can be thought as an implementation of the input boundary as you deliver input events down to your business logic (or domain model) - it's the controller. LiveData is more like the output boundary implementation as it uses observer pattern under the hood and deliver the data back to the UI through the interactor. In this case, I think this makes the ViewModel a strong candidate for being the interactor since it receives the input events (and commands corresponding those events) and also contains the LiveData instance to be observed. Are all these decoupled nice, or, polymorphically deployed? Well, this is mostly related to your design. And with coroutines, now it seems like there's no need for callbacks/listeners - so another dimension into this picture.)
This is my take. I hope it's clear.
It's MVP pattern. Yes as you said it's mediator between presenter and data(as a form of rest call or shared preference or Sqlite).
how does a good architecture for an android app look like? Should all the "work/business logic" been done in a background service and the Activity communicates just with the service to query/fetch data from somewhere (local/distant)?
Would you implement the "service" that the Activity calls as a real Android-service? Or a POJO-Singleton that does the work (perhaps using background threads). Or instantiate background threads in your activity for time-consuming actions (query a webservice).
How do you abstract your data access the right way? Would you use a ContentProvider to access/abstract your data? How/From where should it be queried? Activity? Service? ..?
I've tried to search for a good app architecture design, but I only found how the Android architecture looks like, not how an Android app should look like.
So what's your opinion about that? What components of an Android application should communicate which each other to ensure best extensibility/encapsulation,...?
There's no one answer to this question. Good OO design isn't Android specific. I'd say that the rule is - if the framework gives you a high level object (such as Service in the case of Android) that fits your use case, use it. If you find yourself making POJO implementations of the same things you get for free with the framework, go with the framework.
As far as separation of concerns, this is standard OO stuff. Don't put anything in your Activity classes that isn't the job of the Activity. Over-stuffing the Activity with methods and properties that the Activity needs but aren't really the job of the Activity is bad - makes the intention of your Activity hard to understand.
I usually separate stuff into sub-packages in my apps.
com.myname.myproject.app - base classes, global application functionality
com.myname.myproject.net - network stuff, network related utils
com.myname.myproject.data - db helpers, providers, etc
com.myname.myproject.model - object model
etc.
As far as communication within your app...
I always have a custom Application class that I register in the manifest. This way, when I have controllers and helpers that need to be a "single instance", I don't have to do all that crazy thread safe singleton stuff...I just keep one global copy of.
RoboGuice is a dependency injection framework that makes this even easier to accomplish...definitely worth looking into. If this interests you, the Google Group for RoboGuice is great and is constantly filled with the creators of the framework who can basically answer anything you need.
As far as in-app communication, I use my single instance Controller and State classes to hold state and do common tasks, and I usually use BroadcastIntents to communicate back to Activities from Services