Jan 31

This post is my 2 cents contribution to the debate on persistance stack architecture. I try to write short post (the shorter it is…the understanding greater is), but this time —with such a topic— I can only fail on this point. So this post will be followed by other posts :-).

I will not start from scratch explanation on the different approachs, the wording and so on…you will find some links in this post that I find usefull and I do not want to be redundant with them. I would like to enlarge the scope of the persistance stack to higly customizable environement and also the various features required by an Entreprise Management Application (taht I will name EMA) relying on a persistance layer.

What are the different layers (required or not)

You will find here an excellent article on the different layers of a typical persistence stack and further…to the UI. The UI is key but I will not address this question in this post. You will notice the author talk about a Persistence Layer which is different from an Persistence Stack. I use the word “Persistance Stack” to express all the layers that are requiered to build an application that use a database without the UI. These layers are usually (from the upper level to the RDBMS middleware):

  • Service Layer
  • Domain Layer
  • Data modeling
  • Persistance Layer
  • RDBMS middleware 

About the interest to respect layering

It’s just about commion sense : by layering correctly you will decouple your code and allow easier replacement of components as there are inricated. Most of the time, developers are doing naturally as it give an impression of over complicated the code. The important point they have to though about that an Entreprise Software relying on database will grow and evolve (faster at the begining) and you will write at the end touthands lines of code. If the rules and delimitations are clear from the begining, you will avoid a real mess of large classes.

Now let see in details the aim of each layers. I will go from down to top to express clearly the boundaries of each layer (starting from top tempt to mix the layer and put the code/requirement at a higher level than it should).

Persistance layer

The persistance layer is juste about persistance…obvious but not always respected. Persisance is only about storing and retreiveing data, nothing else. You can use an ORM (Object Relational Mapping) framework as Hibernate or TopLink for example. It’s only bout storing, that means no validation, no business logic at all, and the objects should be limited to structures, no methods. There is no real interest to build it’s own persistance layer as most of the time your requirement are fulfilled by the most advanced frameworks. That does not means you should not take care in the choice of this framework as this layer is the key for the performances: having a poor framework (even a rich ones depending on how you will use them) will dramaticcaly impact performance by generating useless or not optimized RDBMS queries.

Most of the time these objects are named DAO objects or DAL objects (for Data Access Layer objects).

Tow extensions to EMA that may be include in this layer are rights and partitioning. Rights management is the ability to give read/write access to attributes of the DAL objects. The Partitioning is the ability to segregate the read/write access to DAL objects. These fucntionality have obviously a business aspect,e specially for the partitioning. But for performance reasons (espacially for partitioning which is usually implemented using a where statement), this might be implemented in this layer.

ORM..a myth or not? 

The different post, disucssions and articles I’ve read about persistance stack are highlighting the interest of doing OOP (Object Oriented Programing) especially in the domain layer. Most of the argument yield to the mandatoiness of using an ORM which is the key pivotal framework to step from a relational database to a obejct oriented coding space. This a myth to me and is only relevant for folks that love OOP and particularely love debate about the beauty of it.

ORM use have to be limited to what it is design for: just create DAO objects for upper layer. Some folks abuse of this because they are mixing it with the higher level layers which is strong mistake. I’ve looked at Hibernate and NHibernate (to simplify: NHibernate have the same capabilities than Hibernate v2, but in a .Net environment). As a framework it provides lots of different ways to operate with the RDBMS layer, but you usually use on 10% of them as you are doing some assements. IMHO, this is not a mistake to do so, if you take care that this assement will not have a strong impact on the other layers. You will never be able to take some decisions that have absolutely no impact, but you can mitigate this.

An example of assement is to chose the same type for keys: there is a real advantage to do it, but it will have an impact on the Domain Layer and the evolution of your application (if the type is long…evolve to GUID for example may be tricky if they are exposed and used in the other layers). On this specific point, a good practice is to never expose internal keys outside of the layer but to expose business keys in the Service and Domain layers. For each object, exposing 2 kind of business kay is useful: an international one, and a business one. The international one is a key that won’t varie from a language to another, that is usually a sequence of numbers, which is used by external programs to synchronize data for example. The business one is a key that is usually used by humans over business process as a social key for a employee for example, or a barcode for an asset.

Data Modeling

This layer is most of time mixed with the Domain Layer and Persistence layer, but it can be useful to detail its contract.

In my opinion, part of the contractrthis layer is the dual of the relationship aspect in RDBMS. I deed, you have to define the relationship between various objects in the persistance layer (as a purchase order have order lines for example), but you have to define some low level behaviour. Some of you could say that I start to introduce some business logic here…no, i don’t but you are right: we should not introduce business logic here yet. The behaviour I’m talking about are related to the impact on relationships and complex custom types during CRUD (Create Retrieve Update Delete) operations made by the persistance layer.

A complex custom type is a type that rely on more than one attribute of a DAO object. Here are 2 examples.

Currencies: Handling of currencies is not simple, you have to be able to do arithmetics operations on them, and convert them. Obviously a double type field is not enough, neither a string (when I say string, is a string having only one information, not a string containing an xml description of a currency object with multiple attributes). So in the data modeling you could declare that the currency attribute of the value object will be rely on a set of attributes (amount, currency symbol, reference value in $, date of reference convertion) of a DAL object.

Enumeration: Some enumerations fields may have these requirement. First: the user can add new values. Secondly: some values used by the business layers may not be removed. A typical example is the status of a purchase order. The aim is to present some choices to the end-users (all values already entered by other users for a status plus some predefined fixed values). For technical reasons you may store a predefined fixed value in an attribute and other values into another field, but you want your applciation not to be aware of this.

As you see these are low level behaviour. That the same for relationship: if an object of type A is linked to an (or a collection of) object B, B should be deleted if its parent (from a relationship perspective) A is deleted or B should be attached to another object of type A? Does it makes sense to have an object of type B without an association to an object of type A? All this behaviour have a business rational but this have to be implemented in this layer.

Regarding this last sentence, it really make sense to gather together as much as possible the configuration of almost all layers inside one location. In a metadata driven environement, this is absolutely not an issue to mix configuration of different layer inside a unique location (a file or a a folder)…more over, I would recommend it.

Where do I put business logic?

To continue here

Other interesting links
Segregation/Distinction between Service Layer and Domain Layer