I am trying to understand MVP design pattern practically and went through this link and few other links and made some observation. I want to know that all the below observations are correct for implementing MVP design pattern practically?
Activity, Fragments and our xml layouts will be part of View.
Our POJO classes or the classes which are responsible for fetching data, making API calls or calling Web services are part of Model.
We create an interface which contains abstract methods for various events we need to perform on View or various events for the lifecycle of view. Activity/Fragment will implement that interface and pass its reference to Presenter constructor.
Presenter will have reference to both View and Model. Its constructor will contain reference to an interface which Activity implemented and it will create an object of Model.
Whenever an action is performed on View or for any lifecycle callback of View, a method of Presenter is called from View. That method will interact with both Model and View as per requirement. It will call method of Model and will call the method of interface that Activity implemented so both Model and View can perform action in their classes.
Your understanding is mostly correct:
Correct.
Quite correct. Although note that in MVP design pattern terminology the notion Model (M) is pretty general. In practice Model is divided in a few layers depending on their "functionality", e.g. Interactor, Repository, network etc.
In general, correct.
Correct regarding the VP part and incorrect on "it will create an object of Model". Presenter should not create an instance of Model, it should communicate with it via an interface too.
In general, correct. However, View should not care about lifecycle of View. Model should provide data.
Related
I'm getting started to use the mvvm pattern to structure my android application, and I want to maintain its pattern by letting the view to observe data from the viewmodel but in cases where there is need to only observe data when needed or once(such as navigating to a new layout), I find it difficulty to implement this case. Please is it possible? and how exactly can it be done through code(kotlin)?.
I think that it's bad decision, cause your ViewModel shouldn’t know anything about the View and everything from ViewModel should 'push' to View using DataBinding or Observer-Pattern.
The ViewModel is responsible for wrapping the model and preparing
observable data needed by the view. It also provides hooks for the
view to pass events to the model. The ViewModel is not tied to the
view however.
source
Even if you decided to do such things, then you have to understand that it can be difficult to manage subscriptions when view is destroyed.
When you wanna observe something only once, then you have to write your own extensions for LiveData (here you can find example).
Also you can read this article to make sure how to deal with single-events.
If you just ask how to call something from ViewModel, when some concrete event occurs in your View, then the best solution here will be simple call method in ViewModel from your view in listener of widget(button etc)
I work on rewriting my app to MVVM architecture concept.
Based one my understanding all the business logic should live in the ViewModel and the UI components in the Activity or Fragment. I use a third party library that needs to be initialized with some view's like: MyLibrary instance = new MyLibrary ("key" , imageView, surfaceView) and then doing some manipulations on these views.
What would be the best place and the right way doing that knowing that it's not recommended passing any Android view to the ViewModel and also not the right thing to initialize SDK in the Activity
You have already answered your question. It's the other way around, the ViewModel informs the View (activities and fragment) WHAT should be chaged, and the View simply handles HOW it should be updated.
Most of the business logic however, if we want to be nitpcky, should still remain in the model. The ViewModel only holds the LiveData that the View needs. Some reasons for this is that you don't want your model to be Android architecture dependent. But also to follow the single purpose principle. This way you avoid making the ViewModel into a God object that handles everything. Instead you only allow it to format data, pass commands, provide factory methods for binding
to the viewModel, and subscribing/getting relevant changes from the model.
So in short: The View passes user-input to the ViewModel who issues commands on the Model. The ViewModel then format the changes from the Model and posts the changes using LiveData to the View. The View finally updates the components that the user can see.
Check the example here for how the UI is updated.
https://developer.android.com/topic/libraries/architecture/viewmodel
Read more about the pattern here:
https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel
I was wondering whether android binding is compatible with live data on conceptual level.
There is a simple task: call server after button is clicked.
So in my view I have
android:onClick="#{viewmodel::onOrderButtonClick}"
and proper onOrderButtonClick(View) method is defined in ViewModel.
But in order to make server call via LiveData I need my Fragment reference (observe() method needs LifecycleOwner instance as first parameter).
Of course I cannot hold reference to fragment in my ViewModel.
What is the pattern here? Do I really need to implement all event methods in the fragment class and delegate them back into view model class?
After some digging there is a bad news and a good one.
The bad news is that the fragment has to be used anyway (there is always some code in the fragment for each livedata event)
The good one is that it can be done relatively clean:
Call getOrderObservable() from fragment to view model. It returns
MutableLiveData<> created in view model's ctor.
Then call observe() on that observable In view model's onOrderButtonClick()
In onOrderButtonClick() in view model just call setValue()
That solution in my opinion minimalizes amount of code in the fragment. Still it looks not so elegant to separate making the network call and handling the result
Firstly, I know that with Model View Presenter there are different implementations, and in my mind as long as you have the layers of abstraction clearly defined and doing their appointed roles then how you implement this pattern is open to interpretation. I have been implementing this pattern in quite a few apps where there was just one Activity. I've now started a new project that has multiple Activities and attached Fragments, including nested fragments (ViewPager).
I'm now trying to translate the MVP to this project and I've hit a concept wall and would like some guidance and insights.
So far I've created the above structure and started to do a 1 : 1 relationship with View & Presenter (regardless of Activity or Fragment). I feel that this is OK, however if for example I sent a request to do something from an Activity View to its Presenter, which returns a result to the Activity View how would I go about propagating the result i.e. update all the other Activities/Fragments that are currently not in a Paused() or Stop() state. I feel like in this case there should be a central Presenter that updates all necessary Activity and Fragment Views, but I'm not sure how to go about doing this.
Currently when each Activity and Fragment is created it creates a new instance of a Presenter class, passing in itself as a reference (the Activities and Fragments implement their own interfaces), which the presenter stores as a WeakReference and can invoke the relevant interface methods when returning a result.
According to the docs whenever Fragments want to communicate with one another and the attached Activity you should use a callback interface. With this in mind should I have one callback interface that the Activity implements and the Fragments callback to whenever they request something, so in essence only the Activity would have a Presenter and Model layer that the Fragments have to callback to in order to make various requests?
Sorry if this sounds a bit muddled, hopefully this is clear enough to understand what I want to achieve, and if I’m thinking along the right lines... or totally off the mark!
I think this is okay to have a presenter inside activity. Basically activity is like a controller, it should know about the presenter.
It would be wrong to put a presenter inside a fragment if activity or other fragment needs it too. You can put a presenter inside a fragment only if this presenter is designed specifically for fragment.
which the presenter stores as a WeakReference and can invoke the relevant interface methods when returning a result
Why do you need a WeakReference here? If you have 1:1 relationship then I assume your presenter does not have it's own lifecycle, meaning that it's lifecycle depends on either activity or fragment. There is no risk of having memory leaks because it's not a singleton, right? It should be safe to have a strong reference.
I'm not sure if I answered your question because it looks a bit broad to me. My point is that, fragments are just separated "parts" of activity and you should treat them as parts. If presenter belongs to this part only, then it should be inside. Otherwise it should be in activity. You are right about using an interface to access activity, this is a well-known design approach which Google uses in their examples.
Nope, no interface anymore. You either use RxJava Observables to update all the views as described here or some kind of Bus(Otto-deprecated or EventBus). And you will like it because they make interacting too easy.
I'm trying to follow the MVP pattern. However, I have some doubts on how to handle adapters and view holders on this pattern.
Should I use the adapter as a presenter? Having the business logic?
Or should I pass a instance of the presenter that handles the list logic and then call methods of the presenter when there is any interaction with the adapter elements?
Thank you
There is no exact/correct definition of implementing MVP in Android
To answer your question, in my view the Presenter should not have any Android logic.
As such, the Adapter would be a "View" then i.e. Presenter provides it the data (via the Activity or Fragment) and it just deals with how to present this.
I'd do MVP as follow.
Model - POJO's, parsing, Storing (SQLlite) and retrieving data (http). Obviously I'd divide the POJO's, parsing and DB logic into sub folders - but this all falls into Model for me.
View - Activity, Fragment, Adapters - Activities & Fragment hold reference to a Presenter that gives them data to display. How this data/messages are displayed, look + feel etc. is dealt with in the View.
Presenter - The Middle man, provides the logic to inputs i.e. Button Clicks, retrieval of data, validation of inputs & then passes the result back to the View (Activity or Fragment)
Here's a great article on MVP
Here's a simplified diagram of MVP
Answer modified from this question (also answered by me)