Thursday, November 21, 2013

Android Common Design Patterns (MVC, MVVM, MVP)

The Android SDK does not target one particular design pattern, rather it can be adapted to fit into one or more of MVC, MVP, and MVVM.  You can choose what you like best:

MVVM (View/ViewModel/Model)
The most popular MVVM framework is used with Microsoft's WPF.  The core idea is that the the model is tied to the view via the ViewModel.   The ViewModel is responsible for exposing data to the view, as well as handling actions that happened on that view.  You have the idea of 'observables' which implement a two way binding of your objects.  For example, You might have a collection of items.  It can be set up so that if the collection of items is modified EITHER on the view OR in the ViewModel, both are updated to match.  It's automatic.   You don't need to manually update the View to reflect a new item added in the code from another view or action.  If your items in your view are also observable (set up with two-way binding), updating the content of that item (perhaps a description), will automatically reflect a change to the object.  You can catch the 'onchange' event and take other actions, but the idea is that it's a two way, always synced system.  

In Android, you can follow the MVVM pattern by ensuring that you always have listeners for every action, and ensuring that the listeners always update the view accordingly.  The View in this case is your UI (xml/layouts), the ViewModel would be your Activity or Fragment.  Every action taken in the view should be tied directly to that ViewModel.  There are at least two frameworks that help implement MVVM in Android (Android-Binding and MvvmCross).

MVC (Model/View/Controller)
In the MVC, the Controller tells the View how and what to display.  This is extremely common throughout many languages and frameworks.  The Controller will pass the content from the Model to the View, and also ensure the right data goes to the right place.  The controller handles all the callbacks from the web application (the user clicked a button!), and will handle updating the view as well as the model. For example, in a web application, you request a URL, and the view is generated by the controller and returned.  With more modern web development, it is common to have many MVC patterns within the application.  So-called server side MVC (think ASP MVC or Rails) and front end MVC (think Javascript libraries like Angular.js or Durandal.js - though keep in mind two-way binding that uses Knockout.js is more MVVM).

Many people say Android is bad at MVC because you really aren't constrained to the MVC pattern.  Other frameworks often force a 1-1 ratio for controller (activity/fragment) to view by naming convention.  Android does not.  You can do a lot from your Activities/Fragments (anything, actually) including showing many views for one activity.  Also, you can have different types of binding that can somewhat surpass the 'controller' aspect.  For example, you can force the 'controller' to automatically update a list on change.  You can have a listener to see when that list changes in your activity and then update the model directly.  This is the view controlling some of the action in the model.

MVP is similar to MVC, but instead of the Presenter driving the look of the UI, it's the View itself.  This typically involves binding to the model object.  Actions route through the view to the Presenter to figure out what to display.  The View and Presenter are decoupled so that the Presenter's business logic can be tested without the View being present.  What this means is that 10 views may not have 10 presenters as should happen in MVC.

In Android, there is a certain amount of binding in the SDK.  An example is binding is in a ListActivity.  Changing the model directly affects and modifies the View.  Also, one Activity may have many views and many views can talk to the same or many activities/fragments (logic).  Android more generally follows this MVP pattern than MVC, but it could conform to MVC.

Why do we care about any of this?  It's all about separation of concerns.  When you have a designer who wants to update the views, they shouldn't need to worry about breaking the code lying beneath.  If you want to update the Model, you don't want the view to suddenly stop working.  The ViewModel, Controller, Presenter - any of these middlemen - should handle all these situations.  There are benefits and drawbacks to each situation as well.  Often a language or framework will work best with one scenario.  My personal preference is to use MVVM.  I like two way binding.  I think it removes a lot of code and lets the view handle it's own layout.  But really the important thing is that you can change different areas of your code/view without breaking everything. Your business logic should all be in the same place so you understand the code.  The view code should not be mixed in anywhere else.

Some nice references:

No comments:

Post a Comment