MVC on android: Model change and animation - android

After some thinking/reading (especially following series) I came to accept the following general rules for implementing MVC:
Model - set of simple dummy Value Objects, responsible for keeping the state. Model classes are Observable and notify Observers - i.e. views when changed. Model code could be android agnostic.
View - classes able to keep/update its visual state - based on android.view.View/ViewGroup family - by inheritance or composition. View classes are Model-aware, they receive update of Model's state and re-draw accordingly. All user-input listening code is delegated to Controller.
Controller - all user-input processing code in your activity/fragments. Controller updates the Model, which in turn, will trigger subscribed View update.
Sounds simple and certainly doable in most cases.
Now, consider for example:
Controller/Activity keeps track of 2 Model objects model1 and model2 and changes them based on some application logic.
View receives updates from objects model1 and model2 independently as per design above.
Now, suppose the View wants to show animation based on mutual transition of both model1 and model2 for which it needs to know changes of both objects at one time, or as a single event.
What would be recommended way of doing it, keeping mvc design above in place?
I thought about options:
Have a "SmartModel" which encapsulates both model1 and model2, make the mutual changes/transition and inform the View. I don't like this approach because Model becomes not really just "dumb" state representation, but also drags some application logic from Controller.
Have Controller inform the View about the changes it did on both model1 and model2. In that case neither model1 nor model2 need to implement ability to notify the View, i.e. there is no link between Model->View anymore.
May be there is much better option / I am missing something.
Any insightful suggestions will be highly appreciated.

I think the option 2) is similiar with MVP pattern, controller is kind of presenter to change the view for model.
Model View Controller, Model View Presenter, and Model View ViewModel Design Patterns
If you want to follow the strict MVC way, maybe you need to fire some change event to notify the View observers, so they can know what and how exactly the model changes, so they can do partial refresh and animation.

Related

who is in charge of sort data in MVP Structure, View , presenter or Model?

I want to sort My ArrayList which I got it from the model If I want to put a dropdown to sort my data in Activity to sort in Date or alphabet ...
I must send the request to the presenter to sort my data or Can I sort it in view model?
Should the Presenter sort the list of items or is that a task for the view?
The correct answer is (drum roll please) it depends. Are you using a
UI framework that supports sorting natively? Are you sorting over a
large sequence that would be best performed as a database operation?
Does your UI framework support sorting through the database (e.g.
IQueryable support in many .NET UI toolkits).
There are multiple approaches to MVP. You have the Passive View in
which the Presenter has deep knowledge of the view via an Interface,
there's the supervising controller in which the presenter handles
complex view logic and the rest is left to the view (so again if your
view objects can handle sorting, let them do it if it's not an
expensive operation), finally is the Presentation Model which is
pretty much equivalent to MVVM in which the Presenter exposes behavior
as properties and the View reacts to those properties.
taken from here credit to Michael Brown

What is the lifecycle of the MVP components?

Which component does the application start from? Where should they be created? (If the view is activity, and if you need to respect the independence of the components). Under what conditions can exist multiple Model or Presenter components? And who should manage the change and the creation of them?
i have no answer for my all questions about mvp lifecycle, so if somebody can continue Rohit answer - please
Model is responsible for giving the data whatever your requirements are.
Presenter act as a mediator b/w View and Model and contains the business logic(the
manipulation of data according to the users requirements)
View is the part which is visible to the users all your S.D.K. related code will be here
and the part which is visible to the user will be here.
Notes.
1.The View will communicate with the presenter to get Data from model
2.Model will get the data and give to presenter
3. Presenter will do if any modifications in the data is required and give it to View
4.The View and Model will not contact each other directly
5.All the logic will be in presenter so that it can be tested separately
For Android
The View is Activity where android related data will be present which are a part of Android S.D.K. and it will ask presenter for data which will contact the Model which will give you data from server or locally or from anywhere which will get back back to presenter then to view
The Android related data will be in View only and all the things which requires activity or android context should take place in view only
The Presenter will contain the business logic so that we can write JUNIT tests on it

Two-way binding with RxJava on Android

Recently I've been developing some functionality and it seems to me that it would be nicely modeled with some form of two-way binding.
Example: there's a screen where user can fill some forms and save some content. Later user can come back to that content and edit it. Content is stored in a DB so the content should be fetched asynchronously. I use RxJava and Mosby MVP to create MVVM-style connection between the fragment and presenter.
The problem is that forms should be validated on the fly, so any time some part of the View changes Presenter should be notified. But when asynchronous content from DB arrives (in case user is editing existing content) view can corrupt 'initial' state from DB because of the transition between the states. Also there's a risk of infinite event passing cycle between view and presenter (distinctUnitChanged() doesn't always help with this, because state can alter like 1-2-1-2-1)
I've found 2 workarounds but I am not satisfied with them because they're rather impure and don't feel like idiomatic FRP.
The first one is changing a view in the way that it doesn't send events until it received the first state from presenter.
The second one requires sacrificing Presenter purity. Presenting is setting a flag which tells if we should accept view's state change. It will skip events from view until it will receive the one it passed to the view (initial state).
Things are getting even harder because in Android view can disconnect and reconnect to the Presenter at any time (with or without saved state) and Presenter should be the source of truth.
If anyone has any examples of two-way binding implementation with RxJava or any ideas I would be grateful.
Consider using swichMap() (instead of flatMap()) when loading asynchronous content from DB as switchMap() unsubscribes from previous input validation while the user changes form.
Probably this solves your problem.
Btw. It seems that Mosby MVI module is better suited as traditional MVP for what you are trying to achieve (RxJava, Two-Way-Binding).

Presenter/View/ViewState relationshipts

For example, I have EditProjectFragment which contains few elements:
TextView (project name)
ColorPicker (project color)
Spinner (project type)
Let's see:
Project name will be restored by TextView itself
Who must store project's color?
Who must store spinner's value?
It seems to be ViewState's responsibility. For example, when user picks color, View calls presenter.onProjectColorPicked(color). Then, Presenter will call view.setProjectColor(color). Or View should update ViewState directly, without calling Presenter if it doesn't need?
Another example. User adds photo in EditNoteFragment. User picks photo(presenter.pickPhoto()) -> presenter.addPhoto(photo) called and notify View to add photo to ViewState&show it.
Should View update Note object by itself? Should it be done by Presenter? In the first case it means that ViewState will provide methods like getNote()/setNote(note) that will be used by View. Should I duplicate Note-reference via updating it in View.setNote(note) method? The second case means that I probably should store Note object in Presenter and just update View without passing Note in it. But it looks like a wrong way.
In other words: what View must do without Presenter's help(add a photo to Note object?) and what things with it(button clicks etc)?
Viewstate was meant to be used to represent different states from your View. I.e The view is displaying a loading indicator. so we could say that the view is in the "loading state". So whenever the "state" changes usually a presenter was involved because its the responsibility of the presenter to coordinate the views state. The question is: how do you define state? There is no silver bullet.
I don't think that it makes sense to play such a ping pong game like
presenter.onProjectColorPicked(color)
view.setProjectColor(color)
unless, you say that it goes down to the model (business logic) like this:
View calls presenter.onProjectColorPicked(color)
Presenter calls model.setColor(color)
model informs presenter (via observer pattern) that the model has been changed
Presenter calls view.setData(newModelWithChangedColor) containing the new color
In general: the view is just displaying (via presenter) what the current state of the "model" is.
ViewState is just a little helper to deal with screen orientation changes and process death in a slightly more convenient way (compared to traditional onSaveInstanceState(Bundle) implementations).
So ask yourself: What is the state of your "model". Usually, the view's state is the same as the state of the "model".
In the first example, it seems that it is an issue of color picker and spinner to not save the the picked things internally. Therefore, doing that manually in onSaveInstanceState() for the picker / spinner is the default way the android team recommends to go. So, if you just want to use the ViewState feature to not use onSaveInstanceState() because you find it more convenient to use ViewState then this is fine too, although it is not exactly what ViewState was meant for.

Why Table Views (UITableView) have to have standalone source object that provide them data?

I wonder why all Table Views (also in Android) have to have special object that provide them data ?
https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableView/dataSource
Why Table Views can't be populated from controllers (or Activity class in the case of Android) ?
For example UILabel in iOS can be populated just by setting "text" property
https://developer.apple.com/library/ios/documentation/uikit/reference/UILabel_Class/Reference/UILabel.html#//apple_ref/occ/instp/UILabel/text
Could you explain what is the purpose of such design ?
This is a really great question.
We can break this into two reasons - a general one and a specific one that is a common example of it.
First, though, notice that it's even more than that. A UITableView can have two delegate controller objects, a UITableViewDataSourceDelegate and a UITableViewDelegate. The first provides the data; the second responds to actions taken on the displayed data. Why all these layers of abstraction? Why not just stick it in the UIViewController?
The general reason not to is suggested by the name 'UIViewController'. It's meant to control views. In iOS and I expect in android-land, there is a strong temptation to just 'stick it in the view controller' - leading to the Very Large View Controller antipattern, which you can read about a lot (eg here).
Far better for maintenance and organization for the view controller to lay out views and handle button presses, and some other controller object to handle the well-defined and really quite separate responsibility of providing the data.
It's not uncommon to have some sort of object that handles the data anyway - a shopping cart, or list of real estate properties, etc - that encapsulates additional business logic (providing subtotals, for example) but fundamentally already 'has' the data. In that case, provide a category or a lightweight controller that can 'bridge' between that data and the table view, and pass the model object, instead of an array, between view controllers.
This gets into the specific: in iOS, we have things like NSFetchedResultsController. This is a fantastic class that does a tremendous amount of data sorting, pagination, addition, deletion, slicing, dicing, folding, spindling, and mutilating for you - and it also speaks UITableView's language natively. Pass one of those around and you keep your view controllers clean and tidy and separate from your data.
TableViews do need a special or separate object but they do require an object implement the correct protocol so that it can find the data. In Apple's default implementation, it Uses a UTableViewCotnroller that is a new object responds to these methods as well as does some other things such as making the UITableView the root view of the view controller.
If you do not want to use that object for whatever reason you can still manually add a UITableView to your view controller, then sets its delegate to the view controller. Although it is a good to move it out of the view controller if possible to help keep the view controller small and the data reusable.

Categories

Resources