Hi I am reading this post https://news.realm.io/news/eric-maxwell-mvc-mvp-and-mvvm-on-android/ where they explained very well about mvc, mvp, mvvm. I undertood how mvp design pattern works.
I don't find any drawback in MVP over MVVM. As they suggested this is issue
Presenter Concerns -> Maintenance - Presenters, just like Controllers, are prone to collecting additional business logic, sprinkled in, over time. At some point, developers often find themselves with large unwieldy presenters that are difficult to break apart.
Can anyone explain what does it means with an example & how it can be resolved using MVVM ?
I'm a big advocate of MVP and haven't really tried MVVM. The drawback of the possibility of a Presenter getting out of control is something I've had experience with but it can be mitigated.
In the example from the post the business logic will be relatively simple. There is likely only one model to deal with and not too much complex logic.
Let's think of a more complicated example though. Say you have an app that sells flowers. Once the user has chosen their bunch of flowers they get taken to the order options screen where they can:
add a message to the flowers
choose a gift vase
select postage addresses
choose a delivery date
Then add some domain requirements:
you can't add a message if they're delivering abroad
some areas have different lead times on delivery
some vases are only available with some flowers
This might not be the best UX but putting that aside you now have a Presenter that has to deal with many different Models (account, address, vases, orders) and can very quickly start taking on many responsibilities beyond simply telling the View what to display and passing events to the Model. This violates the Single Responsibility Principle. Also any time a class starts getting beyond 500 lines I start getting upset.
The solution is relatively simple though. You separate all your separate bits of logic out into UseCase classes. I use a relatively simple base class as follows:
public abstract class UseCase<I, O> {
public static final int NO_STATUS = -1;
public Observable<Integer> getStatus() {
return Observable.just(NO_STATUS);
}
public abstract Observable<O> getAction(I input);
}
You specify an input & output type and inject all the models you need in the constructor in the concrete implementation class. The Presenter takes events and input from the View passes this to the appropriate UseCase, this then does the complex logic with the Model and returns the appropriate data to the Presenter to update the View.
You can send periodic status updates back to your Presenter using the status if needed to update the UI state.
This way your Presenter returns to being a simple conduit for transferring data & events between the View and the Model and the business logic is nicely contained in a separate class for each action.
As in the MVVP introduction in the article said:
MVVM with Data Binding on Android has the benefits of easier testing
and modularity, while also reducing the amount of glue code that we
have to write to connect the view + model.
Main differences of MVP and MVVP are:
View layer: In MVP, your View is totally a dumb and passive View. But in MVVP, your View is more flexible because it can bind to observable.
In MVP, your Presenter takes care almost everything because of dumb View, so it will become really big and complicated gradually. Meanwhile, in MVVP, ViewModel have support from View (its a little bit smart :D), especially Data Binding, you can reduce a part of logic codes.
Therefore, you will write a lot of codes for Presenter and they are logically related in which you will find it difficult to break down.
However, many developers prefer MVP because they do not want some business logic codes being part of XML layout.
Related
I have classes MainActivity and MyService. In service I connect with a server, but I also need to update some UI for which I would need Context from MainActivity. More precisely I need to use a layoutInflater and then update the views. Should this be done separately?
Example of one function
private suspend fun setStations(serverText: String) {
withContext(Main) {
for (i in (1..numStations(serverText)))
{
frame = ScrollView( ) //would need context here
layoutInflater.inflate(R.layout.frame_layout, frame)
.
.
.
Generally, you would want to separate your business logic and UI concerns as much as possible, to make the code more readable and testable. To do so, you can follow architectural patters such as MVP, MVVM or MVI, based on the need and complexity of your app.
Thus, in your case you can potentially have a callback setup in your activity, that is called when the service finishes executing its code.
For reference, here are a few great reads for this:
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
https://antonioleiva.com/clean-architecture-android/
Also, here's a sample project that uses MVVM (a pretty common architecture)
https://github.com/skydoves/Pokedex
Typically, such a relationship is organized by the architectural pattern (model view presenter). You should make requests to the server in the presenter and then refer to Activity. This might help you https://github.com/Arello-Mobile/Moxy
I have one Activity and i have created one View-model for it. I have created different classes like
UiUtil( show, hide view, hide key board ), Network layer , Data Base layer, AppUtil( for common functionality like Collection check, String validation, Date Conversion etc)
My question is, In MVVM design pattern is Activity can use these utility classes directly or it needs to use these classes via View-model, if it via view model then in the view-model i have to write a method that just call utility classes method . like below TimeDateManager is utility class used in view-model
class HomeViewModel: BaseViewModel()
{
fun prepareTimeAmPmToDisplay(context: Context, alarm: Alarm): String
{
return TimeDateManager.prepareTimeAmPmToDisplay(context, alarm)
}
}
Architectures are not obligatory, they are recommendational, thus you can change their usage in quite wide range. The only stopper should be a common sense(if it is present of course).
In this particular case the usage of utility class inside an Activity maybe ok, based on your ViewModel construction and its way of communication with View(read Activity).
For example if you have some LiveData that sends some kind of event(for ex. data loaded from backend or alarm trigger) inside your ViewModel and your View listens to it, I think it is ok to use util classes inside an Observer in Activity. Especially if this utils method doesn't depend on any ViewModel or Repository data. The direct utils usage in Activity is not limited by this usecase, though - there are plenty of others.
I understand that this may be an unpopular opinion in modern time of "clean approach" but I believe that this "clean approach" sometimes complicates stuff where it shouldn't, thus if mixing things a bit does not brake overall architecture but rather makes some thing more readable and easy to maintain - I would go for it.
Hope it helps.
My approach toward MVVM is simple, ViewModel is responsible for business logic, dealing with repositories (Network, Database, etc.) and all of the non-UI codes preparing the required data for UI, just like the documentation:
A ViewModel object provides the data for a specific UI component, such as a fragment or activity, and contains data-handling business logic to communicate with the model. For example, the ViewModel can call other components to load the data, and it can forward user requests to modify the data. The ViewModel doesn't know about UI components, so it isn't affected by configuration changes, such as recreating an activity when rotating the device.
On the other hand, ViewModels should not store a context (ApplicationContext is exceptional) and it's preferred that they do not use android APIs at all, so they become more testable (especially in the case on pure unit tests).
Also we are recommended to make use of LiveData in ViewModels and the UI has to observe the LiveData. For example, in onCreate of your Activity, you will call loadMainContent() method from VM, it calls getMainContent(page=1) from repository, and the repository will decide to load data from DB or network, and the result will be set on a LiveData were the View is listening for changes.
TL;DR
Sometimes it's even better to call these utilities from View rather than the VM. I'm pretty sure about your UiUtil also I think TimeDateManager is more view related rather than logic related. In addition, Network and DB layers are more efficient if called through a repository (which is responsible for caching, etc.) and VM can use that repo.
Most of the MVVM examples are dealing with very simple user interfaces.
But lets say I have an activity with many views to update (i.e. lots of data)
As I read in other places, multiple ViewModel objects is a bad pattern.
So, as I see it there are two solutions for that:
Create a single object (and single LiveData for it), that wraps all other data objects.
But there's a problem with this - each data object that gets updated will cause the whole UI to update.
Create multiple objects (and multiple LiveData objects for it).
It means that I need to observe each LiveData object. Is there a problem with this pattern?
Thanks in Advance!
First Point you mentioned : Yes this is not optimal Pattern to do but if you have small data then, separating LiveDatas is more work for less gains
Second Point you mentioned : Yes this is more optimal, you can have a LiveData object for each View you want to update and observe them all from your activity or fragment. There are no issues in this Pattern.
About Mutilple ViewModels :
Multiple ViewModels Pattern in same Activty/Fragment is also an option if you have too many things(LiveData objects or funcitions) happening in one ViewModel. This is only recommended to make viewModels lighter. So only use this if you are having a large viewModel class
Create ViewModels for discrete types of information.
You could for example have a UserViewModel that deals with all state regarding a User. This means you can use the same ViewModel in another context, without pulling data that might not be necessary (as you would if you had a single God ViewModel).
Create as many LiveData objects as you need to model your view.
It is better to condense the data into logical objects, where possible. If only to keep things manageable.
If you have a User, you should use that for your LiveData instead of having a LiveData for E-mail address, Display name, Age, etc. That will make things much simpler for your data bindings. Try to keep things logically grouped together.
I'm learning MVP structure and I trying to figure out:
How to pass data between models?
Each model represents one action and if I need to send data from one
model to another one, how can I properly make it? Should I pass data
through presenter, like
firstModel -> commonPresenter -> secondModel
OR
send data between models, like
firstModel -> secondModel?
And what if these models interact with different presenters?
The Model View Presenter pattern, like most architectural patterns, is quite open to experimentation. The important thing to keep in mind is to separate the View from the domain logic and data handling.
Particularly in Android, it's useful to keep the code as far as possible from Framework specific classes like Activities and Fragments.
In my experience, it's best to let Models communicate amongst themselves, as Observers of each other. The same goes for Views and Presenters, or, in general, any component in the same architectural layer.
AFAIK you have to convert your Domain models to your Ui models in presenter so you have to call a method or a constructor like this in presenter:
ModelOne modelOne = new ModelOne(modelTwo);
please consider DRY principals and do NOT assign each field in presenter itself like this
modelOne.title = modelTwo.title;
modelOne.id = modelTwo.id;
but if you want convert a Domain layer model to another Domain layer model you have to do it in other layers. read this for more info:
http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/
"the presenter communicates with model layer, converts the data to UI friendly format, and updates the view"
also you can find above sentence in this link:
http://iyadagha.com/using-mvp-ios-swift/
I try to understand what the best way is to program a "clean" Android app. I found an interesting article about it where they use a kind of a 3 layer architecture.
Now I read that android uses the MVP design pattern and try to understand this. The way I understand the MVP principle (in the android context) is that:
the Model layer are the logic classes
the presenter are the classes that are "linked" to an XML (the activities)
the passive view are the XML's.
Is this correct?
When this is correct, is it then also correct that the 3 layer model fits perfectly in the MVP principle because:
the presentation layer from the 3 layer architecture fits in the presenter layer of MVP
The business and the data layer from the 3 layer architecture fits perfectly in the model part of the MVP?
I hope my questions are clear because it is a complicated topic for me.
Maybe this clears up my vision (way of thinking) about this...
first thing I wanted to clarify is that MVP or any other pattern for that matter is no specific of Android dev and, can be applied to any other framework.
I think you got the gist of it:
view is usually implemented by activities and fragments and will contain the reference to the presenter
the presenter is that middle man between the view and model. Retrieves data from the model and returns it already formatted to the view so it doesn't need to do anything else but display it.
the model can be seen in a simplistic way as the "data provider". It can be as complex as you want, using internal db, lots of clases etc.
If you are interested in Android apps architecture I suggest you watch this talk given at Android dev summit this year. It is one of the bests I've seen
https://www.youtube.com/watch?v=BlkJzgjzL0c
Even though this question has an answer, I don't think this answer is complete by any means.
MVP is a general concept which can have many various implementations, some of which differ substantially. Moreover, the concept itself is very ambiguous - different people can have different concepts in mind when they say MVP. One of the most widespread ones is shown in the below picture:
Regardless of implementation, the general definitions of MVP components are:
Model: abstraction of "application state storage". The definition of what the "state" is and how it is stored are implementation details. Model implementations should not have dependency on View or Presenter.
View: abstraction of "user interface". The definition of who the "user" is and how it interacts with the View are implementation details. View implementations should not have dependency on Model or Presenter.
Presenter: encapsulates application's business logic. Presenter processes user input events received from view, and alters application's state stored in model in response. Presenter also processes changes of application's state stored in model and updates view in response. Presenter usually depends on both the View and the Model.
If you need more information about MVP in context of Android development, you can find it in this post: MVP and MVC Architectural Patterns in Android
Important issues which need to be addressed while implementing MVP in android are activity leaks which cause memory leaks and app crashes due to background process updating closed activity.
Due to presenter having reference to activity, if presenter can't be garbage collected, activity will stay in memory.
Both of the issues can be solved by using life cycle methods of activity or fragment and releasing resources in those methods so that memory leaks and app crashes are prevented.
Cleaning up of resources related background work can be easily implemented using RXJava, for more information about MVP and MVP with RXJava, see http://www.zoftino.com/android-model-view-presenter-mvp-pattern-example
Here is simplest way to implement MVP pattern in your application android_mvp_login_sample
As you have come to know basics of Clean Architechure. The following example depicts how actual your MVP pattern is implemented.
Example:
interface BaseContract {
interface BaseView {
//Methods for View
void onDoSomething();
}
interface BasePresenter {
void doSomething();
}
}
class BaseMainPresenter implements BaseContract.BasePresenter {
BaseContract.BaseView view;
BaseMainPresenter(BaseContract.BaseView view) {
this.view = view;
}
#Override
public void doSomething() {
if (view != null)
view.onDoSomething();
}
}
class DemoClass implements BaseContract.BaseView {
//Create object of Presenter
/****
* Example :
* BaseMainPresenter baseMainPresenter = new BaseMainPresenter(this);
*/
#Override
public void onDoSomething() {
//Deal with Context here.
}
}
Refer below link for sample Actual implementation with scenario & learn more about Clean Architechure : https://github.com/android10/Android-CleanArchitecture
Here on github
https://github.com/saksham24/Android-Firebase-Mvp-Mvc-Mvvm-chat
i made a repo containing 3 applications with same functionality but written in 3 different android patterns(Mvc, Mvp, Mvvm)
Understanding three different pattern is quite easy if we get a simple good example on them so i made a repo to contribute my knowledge to this developer community.
Also the repository is written using proper java guidelines and conventions(including naming and packages, modules) so people looking for such project can also view this repository.
now
if you want to know the difference between android Mvp,Mvc, MvvM see this explanation by realm
https://academy.realm.io/posts/eric-maxwell-mvc-mvp-and-mvvm-on-android/
if you want to compare three pattern see this wonder full blog https://thinkmobiles.com/blog/mvp-vs-mvvm-android-patterns/
Now I read that android uses the MVP design pattern and try to
understand this. The way I understand the MVP principle (in the
android context) is that:
the Model layer are the logic classes
the presenter are the classes that are "linked" to an XML (the activities)
the passive view are the
XML's.
Is this correct?
Not fully: for the Model layer it is true, but for the Presenter it is not. The Presenter is not linked to XML although it has reference to the View through its constructor. The View is the Activity/Fragment in android.
You might want to check here for a sample MVP app for android.