I read about MVP patterns. When we are starting developing android applications we are almost by default using MVC (we usually have our models in "models" package, views are inside "res" folder and activities are basically controllers.
I have realized that some activities inside my applications are not very readable, they are easy to understand but it take some read it because of the amount of code (for example,set up listeners for seekBars, handling sending data do AlertDialogs,receiving data from AlertDialog, validation of data before sending to server.
I don't see any benefit of starting using presenter (in MVP pattern). Presenter holds reference to activity, and when I want to do something with my view(change some EditText for example), I will call some method on presenter that points back to some method in my view(activity).(Explained here) All interactions with views are still handled inside activities which makes it hard to read.
Currently I implemented presenter layer just like some facade layer above activity. For example, there are methods like BindModelToUiViews() that have lot of code for setting up initial views(controls) on screen. What is best practise to make android activities "clean" and more readable(maintanable)?
Related
I am working on a small application using MVP pattern. My home activity has viewpager with multiple fragments in it and each fragment has its own presenter. Fragments aren't communicating with each other so the activity doesn't have any logic, it is just initializing fragments on start.
So if I would like to implement the pattern by the book and stay true to its principals should I implement presenter also for the activity? And if so what should be its role?
If you want to implement MVP by the book and stay true to its principals, every UI that has user interaction should have a presenter. In this case, if your activity is not interacting with the user, there is no need to have a presenter, and your fragments can have their own. If your activity needs, let's say show a loading to the user because of some data loading prior to show the fragments (this is a user interaction because you are interacting with the user to let them know that something is happening so they should wait), then might be good to consider having a presenter for the activity.
MVP doesn't care at all about whether is an Activity/Fragment/View, it just knows View which is considered as an abstraction of whatever can be shown to the user :)
That is at least, from the 'rules' perspective. My 2 cents is, be flexible, if you see that it actually ends up adding value to you and your project, do it, otherwise, sometimes you have to 'break' the rules or create your own.
For using the fragments with their own presenters, I try to use the presenter-contract classes duo to manage the UI events in the fragments.
For example, Consider a click event to show a toast message in case of two possible outcomes: 1. Save and 2. Delete
Then, I will declare two view contract methods like this:
interface View{
fun showSaveMessage()
fun showDeleteMessage()
}
And then, in the fragment, I will use an instance of my presenter class to display the messages at appropriate times like: presenter.doSaveAction(), the presenter in turn will cause the view to show the toast message.
Also, when I come to the actual logic of the fragment, like for fetching some data from a remote server, I use Interactor class along with the Presenter-View classes to perform it.
I believe staying true to all the principles is virtually dependent on what kind of application you are building. Sometimes, it is more feasible to use MVVM with MVP than only MVP pattern for the app architecture too.
I hope this answers your question, kind of?
Is there a difference between the "newer" Model-View-Intent architecture compared to the "older" ones like MVC and MVVM?
What issue does MVI address? What are the similarities with MVC/MVVM? What are the differences?
There are similar questions already on stackoverflow for MVC/MVV/MVP but none so far that explains MVI.
What is the difference between MVC and MVVM?
What are MVP and MVC and what is the difference?
from my experience each architecture pattern of those was invented to solve specific problem that the previous one ignored or wasn't observed yet.
MVC - Model View Controller
in UI applications the responsibilty of rendering the data to the screen, or the business logic and bind those together at first wasn't clear. so MVC came to define those responsibility to three components, each one has one purpose, and the picture describe the relation between those three components.
View - is the UI component that has all the properties like color, shape, tools to listen to the click events .. etc.
Model - is the component that define the business logic that you want the view to render and behave accordingly.
Controller - is the one who change the model, so if the view has a name for example to save, View pass it to the controller then controller manipulate the model with the right actions.
MVP - Model view presenter
the problem with MVC that there is a great coupling between the three components, if you want to change the view calls, it will require you to update controller and the Model.
and that's clear from the MVC picture, the relationship between the three components is very tied, you couldn't replace one of those components without the other.
So MVP came to provide a more clean solution to the previous problem by separating the Model and the View, keep the interactions between them via the Presenter, Presenter is the middle man that each the view and the model call.
So if you want to save a list of favorites movies, View listen to user (*) action, then call the presenter function that update the model, then model tells the Presenter if that succeed or not, and Presenter tells the View to show the right message.
MVVM - Model View ViewModel
with the rise of reactive paradigm, it was clear that we can provide more separate of concerns in UI Applications by just observing the changes and behave on it.
so for example there is a click in view that need to call an api to get latest tv shows.
this view click will be observed at the ViewModel, ViewModel interact with the model to get the data, and finally ViewModel post those data on the view using other observer ..
so in short, View observe ViewModel to get UI updates, and ViewModel observe View to call the right action with the Model. Observer pattern has proved his worthy in decoupling logic so here you go a new Pattern.
So after talking about the most popular architecture patterns, each one has tried to decouple the UI code from the business code. but the previous patterns doesn't bound updating UI with different states in the same time.
if you had an issue that related to the loading appear with an error message showed at the same time, you will understand what I'm talking about, so to maintain UI state, you have to do extra effort looking what you wrote wrong causing those kind of issues.
MVI - Model View Intent
MVI is based on an old idea called finite state machine, any system or component has predictable, set of states is a finite state machine.
in MVI any update to the UI is defined by new state, you could find this is overwhelming, but imagine that you have a screenshot for each time UI changes, that's the state. you can debug, test, reproduce the state issues now.
how to achieve this, that's the MVI in practice.
any user interaction with the UI, is defined in MVI by an Intent, Intent is what the user need from this action, it could be star a movie, refresh the screen, it even could be opening the screen, in that case the Intent is an initial intent to show the screen with all required data.
which component get those Intents to act according on them, that what you define .. you could use a Presenter or a ViewModel, it doesn't matter, MVI is more a practices than using a new middle component.
I'll continue with ViewModel, ViewModel will get those intents, decide which usecase to call (Model behaviors).
all usecases pass by summer function in the ViewModel, that decide which state that needs to be reflected to the View, it provides you with previous state too, so you have the previous and the new state to update the screen, which reduce the rendering updates, and View get only the new hints to update itself.
and finally MVI is uni directional flow, it starts with the View and ends with the View.
... View -> ViewModel/Presenter -> Model -> View -> ...
MVI is different in the way of managing the state, it's a combination of several ideas to build more stable, and testable app.
A really great breakdown is here: https://academy.realm.io/posts/mvc-vs-mvp-vs-mvvm-vs-mvi-mobilization-moskala/. At it's core, MVI is taking the ideas of MVVM (stateless UI state), separate business logic and models, and putting the reactive framework on top of it. Making things streams of events instead of discrete actions, making receiving elements consumers of transformed streams instead of presentation elements, and making state a read-only, disposable thing that is acted upon explicitly in a very structured way.
This requires that you take a functional approach to writing your application, especially the UI/View part of things. State is not modified, new state is calculated from an intent and a series of use-cases. This is fairly well explained here: https://proandroiddev.com/mvi-a-new-member-of-the-mv-band-6f7f0d23bc8a.
It is intended to address the growing complexity of modern UI applications, who have a non-trivial amount of client-side state that needs to be managed explicitly. As most experienced programmers know, the most complex failures come from state that is being modified in an unexpected way. This state manipulation can result in "invalid" states that your application cannot handle, which is effectively a crashed application. MVI addresses this by making state transitions explicit and carefully structured so that they system never comes to an invalid state, and the state is always understandable.
I'm trying to use MVP in my new project. I have a Single Activity and multiple presenters that can be associated with it.
Presenter1 - Load Activity Data
Presenter2 - Load User data - that can be used in multiple Activities (So this presenter will be used in multiple activities
Presenter3 - User Actions - This can also be used in more than one Activities.
For now, I have used all the 3 presenters for one Activity. Is there anything I can do to use only single presenter to access all the methods for the 3 presenters? Searched a lot, but could not find any relevant reference. Thanks
I'm not sure it is the answer you're looking for but you could try an architecture more like clean architecture and isolate the logic of each of your use cases in an interactor and then inject your three interactors in one unic presenter for your activity.
And later, when you'll need to re-use that logic you will have a LoadUserInteractor and a UserActionInteractor to inject into that new presenter.
If you do not want to create interactors in your architecture you could create an abstract present who have the methods for load user data and user actions and let your activity presenter extends it with the load activity data but I'm not sure it will be long before it cause you some maintenance problems.
I am creating my app with using fragments. I have something like main activity, it has FrameLayout as root layout to hold fragments.
After much thought I have decided to separate my application logic in several parts, for example : MainActivity is responsible for app basic navigation (MainPageFragment, CategoryListFragment, ProductListFragment, ProductDescriptionFragment), AuthActivity is responsible for autherization, registration (SignInFragment, RegistrationFragment, RecoverPasswordFragment).
A little about my app. If you have recommendation or don't agree with app structure, I would be grateful for any critics.
What is the problem, as you can see my MainActivity has many responsibilities. There are four Fragments now but it can be more in the future.
Lets consider next situation. In my MainActivity I have MainPageFragment and this fragment in turn of course has some views. And on click event I need to change fragment, for instance from MainPageFragment to the CategoryListFragment. In this case I have several ways to handle clicks or other events from framgents.
The most common way is to have activity implements callback interface defined in fragment class as nested class inteface. This approach is quite good and easy to use. But what if my host activity has to handle multiple callbacks from fragments, to say more, there can be more than one callback from single fragment, class(activity) declaration starts growing, class body too. What are another possible approaches to solve this problem.
You can handle all clicks, events directly inside fragment (start activity, replace framgent......) you can do this painless, but for me personally callback approach looks better, but maybe there is nothing bad, and I can use this approach.
Use one or several interfaces for getting information from fragments. For example create class CallbackEvent for holding such info as framgentId, eventType .... Using this approach we can reduce interfaces and methods, but Activity class body can become larger in first approach.
Use something like EventBus pattern to communicate between app components via third party service.
Of course there are some other ways to do this, but I have described most popular.
Please suggest, or just explain how to do you solve this problem in your apps, what approach is better, how to built this communication easy to maintain.
I am grateful for any advice,critics in advance.
If your app becomes more complex using the callback pattern will get messy, especially if fragments need to communicate with fragments. I'd only use that pattern for apps with low complexity (activity, one or two fragments).
Clicks, events etc. should be handled inside a fragment if whatever happens stays within the fragment. Don't replace a fragment from within the fragment, that's the Activity's responsibility. It might look easier to just do a getActivity().someMethod in the fragment but this leads to hard to maintain code. You might understand now what it's doing but will struggle in half a year.
This approach looks messy to me too (similar to 1.)
That's the one I'd recommend. I'm using EventBus (https://github.com/greenrobot/EventBus) but there are alternative implementations like Otto (https://github.com/square/otto) and I've never looked back to the times when I used the callback pattern. Using an EventBus decouples the communication between the different components and your code becomes much simpler and leaner. However you need to be careful with that approach since there are some pitfalls. One is that it gets much easier to communicate from any component to any other component which could lead to even messier code than the listener/observer pattern. Another one is that events are asynchronous compared to synchronous listener calls so you need to make sure you're only receiving the "right" events at the right moment in the component's lifecycle. The main advantages of an EventBus approach are IMO:
A message is always an object forcing the developer to code object oriented compared to the more functional listener method calls
It decouples the different components. Publisher and subscribers don't have to know about each other. Decoupling the components will make your code much leaner and easier to read (and maintain).
It can be used by arbitrary components. E.g. I replaced all LocalBroadcastManager calls by EventBus messages (EventBus is MUCH faster that using a LocalBroadcastManager). Being able to communicate between arbitrary components is especially convenient if the components can't access each other directly (like a Dialog and a Preference object)
I have two rules of Fragment - Activity separation.
One is logic. Anything that deals with View (layout expansion, display, listeners, etc) should go inside a Fragment. Important background processes (http requests, file reading, image processing, etc) should go inside Activity. Part of the reason is explained in my second point:
Lifecycle. Activity's lifecycle outlasts Fragment's. Fragment is also fragile it doesn't even retain its views. And this is the reason Fragment should be decoupled from Activity. Listeners and callbacks are tight coupling and they are the cause of countless null pointer exceptions when some process tries to update a View of a Fragment that has called its onDestroyView. Having said this I'd suggest Publisher - Subscriber pattern like Event Bus where you can plan a message delivery in which it gets digested only when a publisher (which in this case corresponds to Fragment's view) is available.
The numerous click listeners you have are related to how you design your UI. Moving code around doesn't really help much, unless you trim down your layouts.
I want as my application to be structured in 2 parts: the logic code and the UI.
I've tried to implement that using a controller class(here I keep the logic code) inside of each activity.
The activity send messages to controller and receive the answer in two ways:
the answer is returned immediately (if the action is not complex and it can be done in a verry short time)
the activity set some listeners and the controller fire this listener when the action is complete.
The problems appears when the controller have a lot of objects(each object should handle a set of actions and for each action I have to set & trigger a listener): it is hard to keep the code syncronized.
I'm asking if you know a better way to implement this mechanism.
Thank you.
Personally, I consider the Activity to be the controller. Widgets are the view. Others may disagree, and I am far from an MVC purist.
Android methodology is pretty MVC.
Start by getting good at Views, then look at extending things as you see fit.
The views connect to the controller via the UI thread, which is the main thread of the application. You can define callbacks and such in the XML and handle all button clicks and such in this thread by just using the android xml methodology.
You should consider XML to be the View, UI Thread the Controller, and Background Threads/Services/Broadcast Receivers etc to all be part of the model.
You can follow "Model View Presenter(MVP)" pattern which pretty much organises the code and keep the code segments clear.
I like the dummy view approach where all views events (like onClick, onLongClick.. ) are delegated to presenter and presenter takes care of the business logic and updates the View back.
Consider a scenario where user is adding some text to his note and In view, we have a textbox, texfield to indicate the status and add button.
User types text and clicks add button.
AddButton: "Hey Presenter! User wants to add something".
Presenter: "Give me your text, TextBox".
TextBox: gives the text typed.
Presenter: Validates the text with buisness logic.
adds item to database using Model classes and sends the status text to StatusTextView to show.
StatusTextView: updates its text which is sent by the presenter.
As you can see, Views do what Presenter says. You can have different flavours of Presenters to act differently to user interactions.
Some points to consider:
Keep presenter out of android classes so that you can unit test it
separately later.
Connect view and presenter with interfaces (contracts) so that you
can plug different views and presenters later with changing app
requirements
Use Dependency Injection frameworks like Dagger2 to even more
decouple the hard dependencies.
Google about MVP and choose your preferred way of implementation. Only con I felt in MVP is your code will become huge yet clear.
Few links:
https://medium.com/cr8resume/make-you-hand-dirty-with-mvp-model-view-presenter-eab5b5c16e42
https://www.journaldev.com/14886/android-mvp
Happy coding :)