Wednesday, November 20, 2013

Software Architecture Patterns: MVC

Long since I have updated here, I went through a number of experiences to land up in developing within the Android platform. Being pushed out of my comfort zone of server-side and database development, it is a fresh adventure by itself in developing mobile applications. Away from my usual rants about software engineering, I would like to be a bit more specific about a topic.

Software architecture can be defined in a number of ways. The software engineering institute has compiled the modern as well as the classical definitions of software architecture.

To be concise, software architecture is a set of models which define the highest level of system abstraction. This may begin with understanding the qualities of the required system and the tactics that enable those qualities. The summed up architecture document will consist of static views such as the Module Layer View or dynamic views such as the Component Connector View. However, somewhere between the requirement modeling and the views exist architecture patterns.

According to Bass et al. in Software Architecture in Practice, an architecture pattern is a description of element and relation types together with a set of constraints on how they may be used. A common example of an architectural pattern is the client-server pattern. Client and Server are two element types  and the communication between them is dictated by a protocol.

One of the most commonly used pattern is the Model-View-Controller (MVC) pattern. Consisting of 3 elements: the Model (the data element), the View (the user-facing element) and the Controller (the element responsible for user interaction). This arrangement of elements helps in isolating functionalities within the elements.
MVC with an active model - Wikipedia

The Controller forms the backbone of the system where it collects information from the user, manipulates the model and returns an updated view back to the user.

The Model can be implemented as active or passive. An active model updates the view on any change that occurs within it. A passive model, however, expects the controller to generate the view based on the changes made to the model.

The View is nothing but the user-facing element which can be described as the output to the user.

A 2008 blog describes the benefits of using this and which of the gang of four (GoF) design patterns fit into this architecture pattern. http://blog.iandavis.com/2008/12/09/what-are-the-benefits-of-mvc/

The MVC pattern has been quite popular with web applications especially within the JavaEE (previously J2EE) framework and in the .Net framework. There have been purely front-end MVC pattern modifications that were used in javascript based frameworks such as Backbone.js. However, with the Android platform, there is a stark difference.

Android applications run on the user's machine. Therefore, the MVC pattern has to be implemented at the user's end. Before going to that, we might need to take a look at the structure of android applications. The entire workflow of android applications is handled by the Android.app components. (http://developer.android.com/reference/android/app/package-summary.html). There are four main components: Activity, Service, BroadcastReceiver and ContentProvider.

The Activity provides the user interface while the Service performs tasks in background. For our MVC pattern, the activity becomes the strongest contender for a controller. The model is defined by Java classes which may or may not use SQLite for persistence. The view can be defined in XML layout files. 

MVC, MVP and MVVM -Source: 

In android, the activity classes can generate the views from the layout resources depending on the user's interaction as well as the device being used. i.e. the view generated for a tablet will be different from a phone. However, the underlying controller (Activity) remains the same. Similarly, multiple activities can reuse the same layouts for displaying similar content. This satisfies the many controllers-many views condition of MVC. Also, the view being natively stateless, enables Android to support the MVC pattern extensively.

One example of the MVC pattern being used is in the github android application (https://github.com/github/android). An example of a class which behaves as the controller is the PagerActivity class (https://github.com/github/android/blob/master/app/src/main/java/com/github/mobile/ui/PagerActivity.java) which listens to the user's interaction directly and picks a view (fragment) that should be displayed. The views are defined by layout files and other xml files (pager.xml https://github.com/github/android/blob/master/app/res/layout/pager.xml) while the model is defined by the database cache (https://github.com/github/android/blob/master/app/src/main/java/com/github/mobile/persistence/DatabaseCache.java)

Many, however, consider using the MVVM pattern within Android. The Model-View-View Model pattern is similar to MVC in many ways. The main difference is that the View interacts with the user and passes the inputs to the View Model. The view in this case maintains its own state. This is common in applications which use RESTful services with a JavaScript based view. The view in that case is the HTML-JavaScript based application running in the user's browser. The View-Model is represented by the RESTful web service which is unaware of the view that accesses it. The Model is the back-end data element which is accessed by the server only. The MVVM pattern enables the system to have many different views while maintaining common control over the business logic.

Within Android, this may be implemented by extending existing UI controls, Fragments or Activity so that they can maintain their state after user input. The ViewModel in this case can be the back-end Services which will run independent of the view. The services may in turn use an SQLite database as the model. It is essential for MVVM that the ViewModel is not aware of the View. This is mostly possible with a service-oriented architecture.

To conclude, architecture patterns, much like design patterns, are used to aid commonly faced structure issues with the software. There may be many scenarios where one pattern would override another. However, any architecture pattern should be judiciously used to meet the user's requirements.