Architectural patterns are the highest level of patterns in the pantheon of patterns in software. Architectural patterns allow the architects to specify the fundamental structure of an application. The architectural pattern chosen for a given software problem governs the rest of its activities, such as the design of systems involved, communication between different parts of the system, and so on.
There are a number of architectural patterns to choose from depending upon the problem at hand. Different patterns solve different classes or families of problems, creating their own style or class of architecture. For example, a certain class of patterns solves the architecture of client/server systems, another helps to build distributed systems, and a third helps to design highly decoupled peer-to-peer systems.
In this chapter, we will discuss and focus on a few architectural patterns that are encountered often in the Python world. Our pattern of discussion in the chapter will be to take a well-known architectural pattern, and explore one or two popular software applications or frameworks that implement it, or a variation of it.
We will not discuss a lot of code in this chapter—the usage of code will be limited to those patterns where an illustration using a program is absolutely essential. On the other hand, most of the discussion will be on the architectural details, participating subsystems, variations in the architecture implemented by the chosen application/framework, and the like.
There are any number of architecture patterns that we can look at. In this chapter, we will focus on MVC and its related patterns, event-driven programming architectures, microservices architectures, and pipes and filters.
We will be covering the following topics in this chapter:
Model View Controller (MVC) is a well-known and popular architectural pattern for building interactive applications. MVC splits the application into three components: the Model, the View, and the Controller.
The three components perform the following responsibilities:
Separation of concerns using these three components avoids tight coupling between the data of the application and its representation. It allows for multiple representations (views) of the same data (model), which can be computed and presented according to user input received via the controller.
The MVC pattern allows the following interactions:
The Django project is one of the most popular web application frameworks in the Python world. Django implements something like an MVC pattern, but with some subtle differences.
The Django (core) component architecture is illustrated in the following diagram:
The core components of the Django framework are as follows:
One of the most powerful components of the Django framework is its automatic admin system, which reads metadata from the Django models, and generates quick, model-centric admin views, where administrators of the system can view and edit data models via simple HTML forms.
For illustration, the following is an example of a Django model that describes a term that is added to a website as a glossary
term (a glossary is a list or index of words that describes the meaning of words related to a specific subject, text, or dialect):
from django.db import models class GlossaryTerm(models.Model): """ Model for describing a glossary word (term) """ term = models.CharField(max_length=1024) meaning = models.CharField(max_length=1024) meaning_html = models.CharField('Meaning with HTML markup', max_length=4096, null=True, blank=True) example = models.CharField(max_length=4096, null=True, blank=True) # can be a ManyToManyField? domains = models.CharField(max_length=128, null=True, blank=True) notes = models.CharField(max_length=2048, null=True, blank=True) url = models.CharField('URL', max_length=2048, null=True, blank=True) name = models.ForeignKey('GlossarySource', verbose_name='Source', blank=True) def __unicode__(self): return self.term class Meta: unique_together = ('term', 'meaning', 'url')
This is combined with an admin system that registers a model for an automated admin view:
from django.contrib import admin admin.site.register(GlossaryTerm) admin.site.register(GlossarySource)
The following is a screenshot of the automated admin view (HTML form) for adding a glossary term via the Django admin interface:
A quick observation tells you how the Django admin is able to generate the correct field type for the different data fields in the model, and generate a form for adding the data. This is a powerful pattern present in Django that allows one to generate automated admin views for adding/editing models with almost no coding effort.
Let's now look at another popular Python web application framework, namely Flask.
Flask is a micro web framework that uses a minimalistic philosophy for building web applications. Flask relies on just two libraries: the Werkzeug (http://werkzeug.pocoo.org/) WSGI toolkit and the Jinja2 templating framework.
Flask comes with simple URL routing via decorators. The micro word in Flask indicates that the core of the framework is small. Support for databases, forms, and others is provided by multiple extensions that the Python community has built around Flask.
The core Flask can thus be thought of as an MTV framework minus the M (View Template), since the core does not implement support for models.
Here is an approximate schematic diagram of the Flask component architecture:
A simple Flask application using templates looks something like this:
from flask import Flask app = Flask(__name__) @app.route('/') def index(): data = 'some data' return render_template('index.html', **locals())
We can find a few components of the MVC pattern right here:
@app.route
decorator routes requests from the browser to the index
function. The application router can be thought of as the controller.index
function returns the data, and renders it using a template. The index
function can be thought of as generating the view or the view component.3.15.14.98