Implementing the application tier in Django

Django is a web framework. It implements the Model-Template-View architecture, as discussed on the Architecture page. Our intention is to use some new technology to re-implement Publishers' Assistant software for a variety of platforms (see the Goals page). Publishers' Assistant has both desktop-GUI-based and Web-based products. Thus, in order to use Django as the framework for re-implementing PubAssist, it is necessary to either:

This page discusses the implications of these two options for how we implement the application tier (the business logic) in Django.

Web-only interface

This is the simpler of the two options, because it would avoid any development at the framework level and only require that we implement business logic in the form of view functions, which are Python functions with a very specific interface: they

  1. accept HttpRequest objects as a first argument (and possibly other arguments)

  2. return an HttpResponse object, or raise an exception

With this approach, our application tier could be "monolithic" in the sense that every request is handled by exactly one function in the application tier (which may of course make calls to other methods, especially on models); this one function would provide end-to-end processing of the business logic before returning control to the presentation tier.

Advantages

This approach has several advantages, namely:

Disadvantages

The advantages of a Web-only interface come at a price, though:

For these reasons, a Web-only interface is undesirable, at least as a long-term plan for the application. (In the shorter term, though, a Web-only interface is still the best solution for a new product, since it will allow people to start using it as quickly as possible.)

Providing both a desktop GUI and a Web interface

We probably eventually want to provide both kinds of interface to users (and, if I had my druthers, we'd also have a command line/scripting interface).

Advantages

Providing a GUI in addition to a Web interface has the potential to make up for the limitations of a Web-only interface, since:

Disadvantages

On the other hand, creating and maintaining both types of interface increases the complexity of the code and development process:

Implications for the architecture

In addition to the inescapable fact that multiple interfaces means more code, providing multiple interfaces has implications for how we think about the application's architecture and how we design functions, particularly in the application tier.

As discussed on the Architecture page (see the comments), I think it makes sense to consider that business logic contains logic specific to the presentation of data. Just to re-iterate the point: suppose we store a book's retail price as a floating point number. It's not the job of either the database tier or the presentation tier to distinguish between the meaning of that data (a dollar amount) from the meaning of a different floating point number (e.g., a height measurement). Thus, it's the application tier's job to translate that data in a way which respects its meaning (e.g., ensuring that it has only two decimal places).

But now we have a problem. It's at least conceivable that different presentation tiers, such as a desktop GUI and a web interface, expect to receive data in different formats for display. The Web interface might expect pure Unicode strings, while the GUI might expect a number. (In reality, the requirements are not likely to be so strict; Django's templating system, at least, will implicitly convert and Python data type to an HTML-escaped Unicode string, unless you tell it to do otherwise.) Thus, there's a need for two business logic functions that translate floating point numbers into the format required by each presentation layer. At a lower level, both of those functions need to deal with floating point numbers that represent dollar amounts, so we now have three functions, where a Web-only interface had only one:

|----|
|GUI | <-> [GUI-specific business logic] <-|
|----|                                     |
                                           |-> [Common dollar-amount logic] <-> | Data tier |
|----|                                     |
|Web | <-> [Web-specific business logic] <-|
|----|

This implies that, by adding another interface, we have lost the "monolithic" character of the application tier: it now has at least two layers, one which provides business logic in common to all interfaces, as well as a layer containing separate "translation" modules which handle the business logic specific to particular interfaces. Again, this picture is based on the assumption that the presentation tier is always dumb, i.e., that it is not responsible for keeping track of the meaning of different types of data or converting from one type to another for display and validation purposes. This may be an unreasonable assumption; it's worth discussing.

Having a multi-layered application tier in turn means that development of application tier functions is a multi-step process. First, we have to define exactly what needs to happen across the whole application tier for that function; second, we need to separate the parts of the function which are specific to a particular interface from the parts which are common to all interfaces; third, we need to define the parameters for the common function; fourth, we need to implement each of the interface-specific functions and the common function; and finally, we need to test each interface-specific/common function pair.

DesignAndDevelopment/Architecture/DjangoApplicationTier (last edited 2008-03-27 15:41:26 by RichardLawrence)