Anatomy and workings of an application

In first chapter I explained the characteristics of the system. This application being part of such system has web browser based interface and it persists its data in the database. Architecture of any such application is bound to be significantly influenced by two well proven design approaches, Model View Controller (MVC) and Domain Driven Design (DDD).

MVC

MVC (and its derivatives) is an architectural pattern for separating user interface of an application from its behavior and data. First off let's admit we are in dangerous territory as far as terminology is concerned. Luckily most of the book doesn't have to deal with presentation layer and most of the confusion is in the world of rich clients. By MVC we would be invoke the presentation architecture as understood in Spring MVC, Ruby on Rails or ASP.NET MVC.

DDD

Model in MVC is not a homogeneous layer for most enterprise web applications irrespective of you use DDD, Transaction Script, or something else altogether. Since, MVC is a pattern to solve presentation issue, it refers to model as primarily objects and all concepts used for getting these objects. But for an application which has to interact with database, model the domain and use remote services it is much richer than can be described using the word model. This is where DDD concepts are applied. Hence, MVC model is the complete domain layer as described in DDD. Domain layer is different from domain model which consists of aggregates, entities and value objects, former includes services and repository as well.

To get started lets see a simple architecture based on MVC and DDD. Since we are using relational database, Hibernate would be our choice for object relational mapping. One can use plain objects in domain layer and map them using Hibernate. This transparent persistence lends itself extremely well for unit testing. Hibernate abstracts the relational database extremely well but at the same time it can hide performance issues from the developers. <placeholder> explains this problem and a pattern to ease it. The diagram lays down different layers of our application. Please keep a note of the fact that in the diagram that there is no service layer. Since we are not using the Active Record pattern [PoEAA] we have a separate repository layer.

<diagram>

From the following table we can see inter-layer dependency. (Each cells reads as: row's header depends-on/unaware-of row's column)

<example code?>

We have started with a simple architecture which would work for sometime. But our application would become complex as we implement more functionality. In the rest of this section we would progressively introduce complexity that we see in our every day applications and modify our architecture based on these. I have specifically chosen this approach for couple of reasons. It gives me flow to write this book. But more importantly we make these modifications to architecture under some context. It is important for us to understand this context and problems posed to better understand why an element of architecture is needed. Also, every additional layer in architecture also brings with it cognitive burden on the developer, slowing down the creative process. Arguably I have chosen a starting architecture which might be overly designed in your case. Though I haven't chosen a randomly under-designed point as well. If you have developed Ruby on Rails application this would look quite familiar to you.

While I have approached the book like this, in no way is this a development process recommendation. Developers should assess the complexity of their application choose the starting architecture based on their judgement. Some team might in fact choose this approach in an uncertain situation. Irrespective of these new layers might have to be introduced in your architecture and it puts forward a question. Should this layer be introduced for all the existing code or just where there is new complexity. Former sets up a high barrier to change and thus impedes it which is worse situation than having inconsistent but evolving architecture.

Application behavior

The server side processing of a web application can be broken up into two categories query and command. One can query a web application for some data and can command it to make some changes. Query do not result in any change from the business perspective, although the application might record the fact that query was made.

Query request processing can be broken up into following coarse grain steps.

  1. Request validation
  2. Domain validation
  3. Domain model query loads the domain objects based on request of the user using the repositories.
  4. In response creation stage the loaded domain objects are used to populate the presentation markup.

Similarly, command processing is staged as:

  1. Request validation
  2. Domain validation
  3. Domain model query
  4. Domain command(s) are executed on loaded domain entities resulting in its mutation.
  5. Response creation (same as query)
  6. Persist the mutated domain entities. (exception: Temporarily Mutated Domain)

During this processing domain entities can be one of the following states.

  1. Persistent: saved to a permanent storage like database.
  2. Activated: loaded in memory to perform business logic.
  3. Mutated: present in memory and different from state in persistent storage.

Data abstractions

Our web application which has a rich domain has different kind of abstractions for data based on its role and behavior. The implementation might choose to reuse the same objects for different abstractions, but let us identify them and give them a name.

  • Web Request represents a single request.
  • View Model abstracts the response used for presenting a page to the user.
  • User Session represents the state of session which is kept alive across multiple requests.
  • Configuration object represents the configurable data for the application.
  • Entity (as described in DDD)
  • Value Object (as described in DDD)

Use continuations: (e.g. excess payment made, warning accepted)

(Think of all aspects of these chapter from rails perspective.

After having moved all the noise from entity one can encapsulate primitives in domain specific concepts. Doing it for meta-data is of not much value.)

http://martinfowler.com/eaaCatalog/

Complementing references

http://fragmental.tw/2010/12/23/how-to-write-a-repository/