MVP and MVC

This is the first post in series of three posts that discuss Model View Controller (MVC) and Model View Presenter (MVP) architectural patterns in context of Android development.

Why you should be interested in MVP and MVC:

Consider this statement by Robert “Uncle Bob” Martin:

The only way to make the deadline—the only way to go fast—is to keep the code as clean as possible at all times.Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship

In case you don’t know who Uncle Bob is: he formulated the First Five Principles of Object Oriented Design (which were later given acronym S.O.L.I.D), was among original authors of Manifesto for Agile Software Development, and you find him by googling for “clean code”. In my opinion, he is an authority when it comes to software engineering.

Proper MVP and MVC implementations have the following characteristics:

  • Readable and maintainable code
  • Modular code which provides high degree of decoupling
  • More testable code
  • Code which is fun to work with

The above characteristics are generally associated with “clean code”. Therefore, following Uncle Bob’s reasoning, adoption of MVP or MVC allows us to “go faster” with our projects.

Outline:

Part 1 of the series (this post) will provide a general definitions of MVP and MVC architectural patterns, followed by discussion of applicability of MVP and MVC in context of Android development.

Part 2 of the series is all about “view” component. It shows how to properly abstract application’s user interface by extracting UI logic into standalone, independent classes.

Part 3 of the series discusses “presenter/controller” component.

Core concepts and techniques will be presented using fully functional open-source tutorial application. This application was written for the sole purpose of demonstrating the power of clean MVP/MVC implementation.

There is also a real world open-sourced application that uses the approach described in this series of posts. Source code of this application can serve as a “reference” for more advanced cases than those presented in tutorial app (e.g. Navigation Drawer).

Model? View? Controller? Presenter?

MVP and MVC are architectural patterns. The idea behind them is that many software systems that have user interface can be divided into three components:

  • The component that stores system’s state (whether this state persistent or not). This component is referred to as Model.
  • The component that handles input-output from/to the user. This component is referred to as View.
  • The component that encapsulates the logical functionality of the system. This component is referred to as Controller/Presenter.

Components of a good MVC/MVP implementation should be decoupled as much as possible: it should be possible to switch from one input/output entity (View) to another, or to change the location or the type of persistent storage mechanism (Model) without affecting other components.

What is the difference between MVC and MVP?

Unfortunately, there is no universally agreed definition for either MVC or MVP. You can find many descriptions on the web, some of which differ substantially. Therefore, before we begin our discussion, we shall omit any ambiguity by providing a concrete definition for each pattern.

If you are curious to what extent can the definitions of MVC and MVP by different people differ – read this thread on StackOverflow.

Interested readers might also read this great post by Derek Greer – we will fully adopt his definition of MVC, but our notion of MVP will correspond to Derek’s “the passive view pattern”.

Now let us put MVC and MVP interaction diagrams side by side and compare them:

 

MVC_MVP

As you can see, these architectural patterns are very similar. The key differences are:

  1. In MVC, the view gets notified of any change in model’s state by the model itself. In MVP, the view knows nothing about the model, and it is presenter’s job to fetch the up to date data from the model, understand whether the view should be updated and bind a new data to the view.
  2. Views in MVC tend to have more logic in them because they are responsible for handling of notifications from the model. In MVP, the same logic is located in the presenter, which makes the views very “dumb” – their sole purpose becomes rendering of the data that was bound to them by the presenter and capturing user input.

The bottom line is that in MVC the view is aware of model’s existence and they interact directly, whereas in MVP both the view and the model know nothing about each other.

Does Android support MVC or MVP natively?

The question is not whether the standard architecture for Android applications recommended by Google is MVC/MVP (currently, it is not as of 2016, some variations of MVx patterns became officially promoted by Google). The question is whether there is anything about Android that prevents developers from adopting these architectural patterns.

The “M” part is fine – it is straightforward to implement a standalone model functionality in Android. In fact, ContentProvider accessible through ContentResolver makes for a very good MVC model once you get accustomed to it – a general, independent of the rest of the code approach, which completely abstracts the underlying storage mechanism.

If ContentProvider is too complex or restricting for application’s needs, a good model can also be implemented using one of the existing persistence libraries (e.g. ORM libraries) , or using custom global in-memory cache.

The problems arise if you try to separate view and controller functionality. For example, the following code snippet was copied from Android Developers website:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Set the user interface layout for this Activity
    // The layout file is defined in the project res/layout/main_activity.xml file
    setContentView(R.layout.main_activity);

    // Initialize member TextView so we can manipulate it later
    mTextView = (TextView) findViewById(R.id.text_message);

    // Make sure we're running on Honeycomb or higher to use ActionBar APIs
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        // For the main activity, make sure the app icon in the action bar
        // does not behave as a button
        ActionBar actionBar = getActionBar();
        actionBar.setHomeButtonEnabled(false);
    }
}

Let’s forget for a moment that this code snippet is trivial and analyze it in terms of view and presenter/controller functionality:

  • onCreate() is a “lifecycle” method which is called by Android framework in response to framework’s internal state transitions. These transitions might or might not be related to user’s actions in the application, but the application never calls onCreate() directly.
    You might get an impression that this method belongs to the “view” part of MVC because setContentView() is called along the way, but, in fact, setContentView() is a standard binding of a view performed by the presenter/controller.
    In addition, onCreate() (and other “lifecycle” methods) takes care of models initialization and binding, resources allocation and app’s state management. All these are presenter/controller responsibilities.
  • Activity also manages the UI of the application. In the above code snippet there are just two references to UI elements (R.layout.main_activity and R.id.text_message), but it is a widespread practice to describe all UI related functionality in Activity.

The conclusion is that in Android, by default, Activities take on both view and presenter/controller responsibilities. If we want to implement MVC or MVP architectural patterns, it is up to us to manually enforce the separation.

Activity role:

Given that Activity, by default, are both the view and the presenter/controller, in order to implement MVC or MVP we need to decide which of these responsibilities should be extracted from it.

This question is not trivial, and there is no consensus in Android community as to which approach is better.

Many alternative implementations of MVx patterns that you might find on the internet designate Activity as view and attempt to extract the presenter/controller functionality. I don’t think that this is the optimal approach and prefer to see Activity as presenter/contoller and extract view functionality.

The justification for treating Activity as presenter/controller is given in this article: Activities in Android are not UI elements.

Which architectural pattern is more suitable for Android development – MVC or MVP?

We’ve already seen that MVP and MVC architectural patterns (as defined in this post) are very similar. Still, since we discuss Android development, there are aspects of Android framework which makes one of them a more suitable choice for application’s architecture.

My personal opinion is that MVP is better for Android because it is simpler and cleaner to have independent view and model components.

If we allow the view and the model to communicate directly, we might end up in a situation when the view needs to become aware life-cycle events. Since these events are not directly related to UI management, making the view aware of them breaks the abstraction of application’s UI.

Since complete UI abstraction is very important for achieving “clean code”, I prefer MVP over MVC for Android development.

Conclusion:

In this post we reviewed MVP and MVC architectural patterns in general, and also discussed their applicability in context of Android development.

The next post (part 2) shows how to abstract UI management logic into “view” component.

Please leave your comments and questions below, and consider subscribing to our newsletter if you liked the post.

This article has 16 comments

  1. Mahdi Pishguy Reply

    how about MVVM on Android? could you write useful post about it? which is better and we can simply manage Activity lifeCycle?

    • Vasiliy Reply

      As I said in the post, there is no universally agreed definition for any MVx pattern, therefore I can’t really know what you mean by MVVM. Some people even call the same pattern I propose here MVVM, and I don’t argue with them 🙂

      • Alex Reply

        Hi, Vasiliy. I just read your message from stackoverflow.com. Actually I had to post that question about MVC and MVP after reading your posts here because I don’t get it clearly from here. Also, I don’t have any practical experience in development of Android. All I have is the conceptual idea of MVC(putting all things together) from my tutor. Even my tutor couldn’t well explain the differences between design patterns and said in China there’re many posts up there in the Internet regarding these patterns but variants of those abound as well. People hold their concepts of design patterns based on their own understandings of them, hence no unity. Sometimes I read an article from an accredited Android master on MVP, all in explicitly details, just when I thought I finally had a basic understanding of what’s going on with this pattern, I read the comments below, there’re voices that disagree. I am struggling to find an example from an authoritative source to learn but failed to find one, even googlesamples from github, too complex….and also I get confused with business logic, how to define business logic? Say a login interface(UI), does input username or password count as business logic? Does click the login button count as business logic? What can be included as business logic? Is there a rule of thumb? Thank you!

        • Vasiliy Reply

          Hello Alex,
          Thank you for your questions.
          I tend to agree with your tutor about MVx family of patterns (MVx = MVC or MVP or MVVM or etc.) – there is no universally agreed definition for them. I myself was thinking a lot about what is the main characteristic of MVx patterns. What I concluded is that if application’s UI logic is being encapsulated into independent components that can be easily replaced with alternative implementations, then this application can probably be seen as MVx.
          But even if we adopt the above heuristic for the definition of MVx family of patterns, we would still need to define “UI logic” (or its complement – “business logic”). This is a non-trivial task by itself.
          The heuristic that I use for UI logic is the following: if I change input method from GUI to command line, which parts of my application become obsolete? The parts that are not used anymore (because the user’s input obtained via command line) constitute the “UI logic”.
          Applying this heuristic to your examples show the following 1) UI elements that allow the user to input username/password belong to “UI logic” 2) Login button and the associated click event belongs to “UI logic”.
          And one last piece of advice: it will be better for you to get practical experience in Android development (e.g. constructing simple, but complete application) before you deep dive into advanced stuff. Since Android does not have a pre-defined “template” for any of MVx patterns, discussions about them immediately falls into “advanced” category.

          • Alex

            I see, thank you for your patience in answering my question. Your advice of defining logic coupled with how you think along the way does help me in codes reading and writing. I will practice that. Apologize that I may have misled you by saying practical experience, by that, I meant practical working experience. I came out of a short-term training school with hands-on experience in Android development only. And I got canned recently shortly after I put my finger on that project. Guessed I didn’t make them happy because of either low efficiency or incompetence. What I have learned from the training school is far different from the development of projects in real world. In school, the teachers use MVC only and do not emphasize much on distinguish what’s business logic and what’s model or things like that. On an unrelated note, is there a chance that you would begin to recommend books on Android once a while? I know you’re busy with your new project IDoCare. Please do not reply “Google does.”, XD! Thank you!

          • Vasiliy

            Alex,
            I was sad to hear about your first professional experience as Android Developer. However, in my opinion, the mere fact that you seek for information and ask for books advice is a strong indication that you’ll end up being an excellent developer. I’m not trying to be polite here – most Android developers that I met hadn’t ever read a book on software development. Those who had clearly stand out.
            As for books – this is a great idea. I’ll write a post on the topic. However, I’m not aware of many books about Android development and personally read just two. Unfortunately, I can’t recommend either of them. But if you’re serious about software development, then get a copy of Steve McConnell’s Code Complete 2. It is long (800+ pages), but its content is pure gold. At the end of a day, Android development is software development at its core.

  2. Jack Reply

    Hi Vasiliy. Thanks for these great posts. I don’t understand the following content well.
    “If we allow the view and the model to communicate directly, we might end up in a situation when the view needs to become aware of Activity or Fragment life-cycle events.”

    Could you give an example of this?

    As I understood, when View and Model communicate directly, they are changed based on user interactions such as entering some search keyword, performing a query and/or showing query results from the network. It seems not related to life-cycle callbacks (onCreate( ) etc.).

    I have very limited experience in Android. Forgive me if it sound naive.

    • Vasiliy Reply

      Hello Jack. You’re right – this statement requires justification.
      Except for querying the model, we will usually also want to register observers that will be notified when the model is changed in some way. These observers must be unregistered from the model when view/controller pair is no longer needed (e.g. user navigated to different screen). Forgetting unregistering the observer might cause memory leaks in some cases. Register and unregister actions are usually done in controller’s onStart() and onStop() methods respectively. If you delegate this functionality to MVC view, then we can register observers in constructor, but there is no corresponding “destructor”.
      In order to prevent memory leaks, we’ll need to introduce some sort of life-cycle into MVC views. This life-cycle will probably reflect part of controller’s life-cycle, or, maybe, part of Android View’s life-cycle. During my initial experiments with MVP/MVC in Android a couple of years ago, I tried this approach. It is complicated and ugly. Not only I had to keep in mind the life-cycles of Activity and Fragment, but also this new view’s life-cycle. It also results in much more boilerplate.
      Therefore I decided to keep the views “unaware” of model’s existence, and let controllers manage everything.

Leave a Comment

Your email address will not be published. Required fields are marked *