Table of Contents
Web application systems, like any other complex engineering artifacts, need an architecture that helps master their complexity by breaking them down into smaller parts with manageable inter-dependencies. Software application architecture is concerned with the following issues:
The state structure of the application system to be designed is defined in the form of information models describing its information architecture.
The goal of a code base architecture is to structure and partition the overall program code of an application in such a way that the fundamental software quality goal of maintainability is achieved.
The distribution of the application system's runtime components within a computer network is defined by a deployment architecture. A web app is distributed on the Web, which is a world-wide client-server network system with HTTP-based communication.
As in all cases of designing a complex system, no matter if a new building, a new space shuttle, a new computer or a new software application is to be designed, an architecture provides a kind of master plan for defining the structure of the system. Any good architecture is based on the following three principles:
Complying with these principles makes it easier to develop, or source, and update certain system parts independently of others.
The three most important parts of the code base of an app are:
the model, which implements the app's data model in the form of model classes, defining suitable data structures and constraints;
the data storage management procedures, which set up a connection to a storage management system (typically, but not necessarily, an SQL database system) and use it for storing and retrieving persistent data;
the user interface (UI) code, taking care of both information provision (or output) to the user, e.g., on the computer screen, and user input provided by user actions in the form of UI events, e.g., keyboard or mouse events, such that all required user interactions are supported.
The onion principle requires to keep the app's model classes independent of
the UI code because it should be possible to re-use the same model classes with different UI technologies;
the storage management code because it should be possible to re-use the same model classes with different storage technologies.
However, in many web application frameworks (e.g., in Java EE) the onion principle is violated.
The most popular and most widely used approach in software application architecture is the Model-View-Controller code partitioning pattern. Although it has not been precisely defined, and has been implemented in many different ways, especially in web application frameworks, it is based on the principle of separation of concerns and on the fundamental insight that the model is the foundation for all other parts of an application, in particular for the user interface. Consequently, even if the MVC approach doesn't provide a precise definition of what a 'model' is, we can consider it to be a model-based approach.
According to Wikipedia, the first MVC architecture was introduced to application programming with Smalltalk-76 by Trygve Reenskaug in the 1970s. In a later article about Smalltalk-80, MVC is explained as a "three-way division of an application" that entails "separating (1) the parts that represent the model of the underlying application domain from (2) the way the model is presented to the user and from (3) the way the user interacts with it". The authors, who also use the term "MVC metaphor", point out that their approach would allow programmers to "write an application model by first defining new classes that would embody the special application domain-specific information".
Notice that the model is defined to consist of classes that capture the required domain information. We call them model classes.
In this original MVC approach, there is no well-defined concept of a user interface (UI). The 'view' is defined as comprising the output side of a UI, only, while the user input side is separated from it and subsumed under the term 'controller'. This does not reflect how a UI is really organized: by combining certain forms of application output with certain forms of user input like two sides of the same coin. A general UI concept includes both the output (the information output provided to the user, as well as system actions) and the input (including information input provided, as well as actions performed, by the user).
The Smalltalk MVC metaphor was developed for (monochromatic) text-screen-based user interfaces with no general notion of UI events. This may explain why they did not consider an integral concept of a UI. While they distinguished between the state of objects in the model and their state in the UI, which are both in the scope of a user session, they did not consider the distinction between the model state and the database state.
In his web essay GUI Architectures (2006), Martin Fowler summarizes the main principles of the original MVC approach in the following way:
Separation between UI and model.
Divide UI into a 'controller' and 'view'.
Views are synchronized with the model (by means of a data binding mechanism).
While the first and third principles are fundamental for the architecture of software applications, the second principle has just a historic meaning and was soon abandoned by the developers of Smalltalk.
Compared to the 1980s, computers, human-computer interaction and software application architecture have evolved. In particular, the establishment of the Web as the predominant computing platform has made web browsers to be the most important infrastructure for user interfaces.
The MVC terminology is still widely used today, especially by web application frameworks, but with different meanings ascribed to "M", "V" and "C". Typically, the "view" denotes the app's code for the HTML-forms-based user interface, and the "controller" denotes the code that is in charge of mediating between the "view" and the "model".
In many MVC approaches, the "model" is tightly coupled with the underlying database technology, often via an object-relational mapping (ORM) approach mapping classes to tables and objects to table rows. This tight coupling between model classes and database tables violates both the fundamental principle of minimizing interdependencies (because there is no need that model classes depend on database tables) and the onion principle discussed below.
For instance, in the Active Record paradigm of the influential Ruby-on-Rails framework, which has been adopted by many other web application frameworks (such as by CakePHP), the "model" is a direct representation of the schema of the underlying database system, where each entity table of the database is represented by a "model" class that inherits data manipulation methods for performing Create/Retrieve/Update/Delete (CRUD) operations. In this table-to-model-class mapping approach, the "model" depends on the schema of the underlying database and is therefore tightly coupled with the underlying ORM technology. While this may be a suitable approach for a database-first development methodology, where an SQL database is the foundation of an application, it is certainly not a general approach and it turns the model into a secondary asset.
Also in frameworks based on ORM annotations, such as Java EE with JPA annotations, the C# framework ASP.NET MVC with Entity Framework and Data Annotations, or the PHP framework Symfony with Doctrine annotations, the "model" is coupled with the underlying ORM technology through the ORM annotations woven into the model code, thus making the model dependent on the ORM technology used. All these frameworks use the Data Mapper approach for performing CRUD operations based on ORM annotations.