Model View Controller Pattern in Android (Part 1)

1. Introduction

Design principles like code reusability and separation of concerns are the central ideas behind the Model View Controller pattern. Like other Java UI toolkits Android UI framework is organized around this pattern.

1.1 Model View Controller

But what is model view controller? The main idea of model view controller is to divide all objects in one of three "camps":
  • the model "camp"
  • the controller "camp" and
  • the view "camp"

The three "camps" of the Model-View-Controller

But what are these three Camps?

1.2 The Model

The model camp is what your application does. For example, if you're building a spaceship shoot 'em up game this is where the spaceships are in outer space, what planets are and where they are. Which guns every ship has and how much damage it can take and so on.
Those are all part of what the program is. It represents space ships in outer space. That's its model.
But notice the model doesn't know anything about where the ships are on the screen. The ship on the screen has nothing to do with the model. That's where the controller and the view comes in.

1.3 The Controller

The controller you can think of as the objects that control how the model is presented on the screen. It's a kind of a glue. It's the thing that takes the space ship's position in outer space and figures out how to show this on screen.

1.4 The View

And the view is the controller's minions. The view is just objects that your controller uses to do what it does, to get this thing on screen. We try to make objects in the view camp as generic as possible, like buttons and sliders. They come from Google and they don't know absolutely nothing about the application they're appearing. It's up to the controller to take these generic minions and use them to do what needs to be done to display the model on screen.

1.5 Communication between the Camps

Once you have all these three camps than it's all about managing the communication between the camps. What communication is allowed and how we achieve that communication.

Let's talk about the controller talking to the model. This is a controller object that wants to send a message to an object in the model and that is 100% allowed. Green arrow going in that direction.
The controller always talk directly to the model. Because it's the controller's job to get that model on screen somehow so it needs to have full access to the model. The green arrow goes one way, so it's the controller knowing about the model.

The Controller "talking" to the model

Between the camps there are lines that look like road markers and from the side from the controller to model theres a dashed line that means cross over this line any time you want.

What about the controller talking to its minions - also green arrow. The controller is responsible for getting the model on screen it has got to have full ability to do anything it wants with those views, e.g. set them up, arrange them on screen, communicate data to the view etc.  So that arrow is also green. That side of the road is also a dashed line.

The controller is allowed to talk to the view

How about the the model and the view. They should never talk to each other. I'm sure that you can  understand why the model never talks to a view. The model is user interface independent. You could have a model for a space shout em up game where the user interface is command line. It would be kind of silly but you could.

The other way some people say I want to build a custom view that knows all about my model so I can display it. Well that sounds attractive but the reason why this is not such a good idea is reuse. Because when you write that custom thing tied to the model. Whenever you change the model you have to rewrite that custom thing. Those things are linked in a way that the view can't be reused and also the model can't be reused with a different UI. It's better to put that code in the controller. And try to build a more generic UI object.
The other reason is that if you have a view talking to the model. Now you have everybody talking to the model. Now the model is al little bit like under siege. And when you try to figure out what's going on inside my application it's a lot easier when you know the only the controller is talking to you model.

How about the view speaking to its controller? As mentioned before the objects in the view are generic objects (buttons & sliders) that come from Google and they don't know absolutely nothing about the application they're appearing. So the communication between the view and the controller has to be "blind", which means that the view can not know which class of object it is talking to. Because the communication is "blind" it has to be structured. This blind and structured communication is realized via a pattern quite common in the Android libraries, the callback.

The view talks to the controller in a"blind" and structured way

To define a callback extension point, a class defines two things. First it defines a Java Interface (a Listener) that describes, but does not implement, the callback action. It also defines a setter method that takes, as an argument, an object implementing the interface.

Button is a subclass of View, which defines an interface named OnClickListener and a method named onClick. The interface defines a single method, onClick. When a Button receives a click, and if the listener is installed, that listener's onClick method is invoked. In the activity the code would look like the following snippet:

((Button) findViewById(R.id.button_id)).setOnClickListener(
        // this is an anonymous class
        new Button.OnClickListener() {
            public void onClick (View v) {
                digitPressed((Button) findViewById(R.id.button_id), display); 
            }
        }
   );

/** Handle the onClick Event */
void digitPressed(Button button, TextView textView) {
         // Handling onClick event goes here ... 
}

This pattern is used by the Android Framework pervasively. It is also used for the communication between model and the controller, when the model is updated. This means that there is also a "blind" communication between the model and the controller.

The model talks to the controller "via" the callback