What is Infrastructure? If we think at a building, Infrastructure is what brings light and water. You can build a wonderful house, but if you don’t connect it to the city infrastructures, you will never be able to live in it. Finally this building is able to receive water and light, but is not linked to any specific water or light distributor. I can start a contract with energy company A and change to energy company B if needed.
If we come back to software engineering, Software Infrastructure is what gives energy to our system: a database technology, a network protocol, or a file system implementation. It is part of software architecture, but as for a building the vendor-neutral principle should be adopted, that means decouple the software architecture from any specific infrastructure implementation, to be able to switch easily from a technology to another.
One of the most important part of the Infrastructure Layer is the Persistence Layer. Persistent is whatever an object that is able to live independently of a software. Typically a database is a persistence representation of a certain set of data. As discussed in Domain Layer domain objects usually need to be persisted. But persistence is not directly part of business documents! You never speak about database table with business expert, but you speak about objects. So it is very important to keep the two concerns separated:
- The definition of business objects is part of the domain layer
- The mapping of business objects into a persistence model is part of the Persistence Layer (infrastructure layer)
A possible implementation
In my experience I learnt a way of implementing a Persistence Layer. As basic idea business objects are exposed only via interface. Pure implementation of those business objects are not exposed, and available simply using Factories, also exposed via interface and gathered via Lookup or ServiceLoader. Finally to define the persistence layer with an ORM as Hibernate or EclipseLink, XML mapping is the preferred choice.
I know most of you will complain about the use of XML instead of Annotations, but annotations are too much intrusive for the scope that has been prefixed to separate business objects from their persistence infrastructure technology. Annotations put persistence metadata into the domain object, but what if those objects need to be reused by another application that want to persist them in a complete different way? The principle of separating the two concerns foster Reusability of the domain layer.
Hibernate could be just one of the possible persistent representation we want to give to our business objects; what if also we also want to be able to marshall them into XML? For this reason we could think to implement several infrastructure implementations, and make all of them available to be chosen dynamically at run-time, or statically at integration-time. The scope is that whatever implementation we use, the system has to continue to work in the exact way. It simply receives a source of data, if this source is an XML repository, a database or a file system, by the point of view of the application, nothing must change.
So a perfect implementation of a Multilayerd Architecture is one where a changement on the infrastructure will not have any impact on the other layers.
The Infrastructure Layer is what gives energy to a system, that means you will not be able to run a software without it. So even if designed as the last phase, it is implemented quite soon. It is also possible to implement some fake infrastructure technologies and postpone the final implementation, when domain layer will be fully implemented; this will avoid the risk to continuously change the infrastructure implementation every time business objects need to change.