Three tier architecture with Maven
Last Updated on Friday, 24 June 2011 07:20
Developping large Java applications generally requires a three tier architecture. We won't explain the benefits of three tier architecture in this article. A large number of websites describe these architectures but only a few of them describe how to implement it. We will describe a solution in order to enforce this architecture without needing the goodwill of any project members, because this architecture is implicating many developers or even offshore people, and resumes often by continuously enforce the rules.
To insure the tightness of each layer and to guaranty the good use of each one of them without requiring a perfect knowledge of the architecture by each contributor, can be reached by using Apache Maven. We will describe how to implement this paradigm in a defensive way.
In order to guaranty the isolation, lets imagine that each layer is communicating with the upper layer only by his public API.
We will define our three layers in three distinct projects. The lower layer projects are only dependant of their upper layer, preventing any direct references to the upper layers implementation.We will define a pattern/filter allowing us to distinguish the classes belonging to the implementation from the classes belonging to the interfaces. The presentation layer is always referred as the lowest layer.
Lets take the example of an account managing application. The customer layer, via the account controller requires the account manager to achieve basic operations linked to the account management. We will not linger on the control or service pattern notions. We will essentially look into the relation between the presentation layer tier and the logical layer tier.
As an example, the following classes from the business layer :
There are implementation classes (AccountManager.java, AccountModel.java) and there are the inferfaces , exceptions classes or class types allowing the communication between the layers. The implementation classes should not appear in the packaged jar of your J2EE API, to avoid the lower layer to refer to it.
The GUI packages sits in the project Presentation (uiProject), the other packages are in the Business layer (businessProject). We will define the pom (Project Object Model) corresponding to both projects.
Once this defined, we can generate 2 artefacts per project.
- One artefact containing the API and the implementation
- One artefact containing only the API
We will create a filter allowing to distinguish the classes contained in the jar API of the business layer. Here are the criteria :
In the Maven POM (Project Model) we will configure the plugin jar in order to create a jar containing only the API classes in accordance with the filter above. Our complete artefact being create by default, we now work on our artefact API definition. We will take for example the business layer tier.
Then launch the Maven package command in the Business tier project to generate our jar API.
Configure the eclipse plugin to not reference the project as references. If you don't define it your eclipse configuration will reference the Business layer project instead of your library giving you full access to the implementation
We will now define in the presentation layer tier the use of the the business api
This done, we can now refresh our dependencies on the presentation project tier.
Nous constatons maintenant que le projet uiLayer ne dépend plus du projet Business Layer mais seulement de la librairie business-Layer-api
We now notice that the presentation layer project doesn’t depend anymore on the Business tier project , but only on the business tier api library.
We now have 2 projects, one containing the user interface and another containing the business logic. All references of the interface layer with a implementation of the Business layer will not be made without generating a compilation error. Our layers are isolated.
There can't be any circular reference, neither any reference going in the opposite direction, neither any other reference than the API.
Terminology used by Domain-driven design
- Entity: An object which has a distinct identity. For example, a User entity has a distinct identity with an ID.
- Value Object: An object which has no distinct identity, like numbers and dates. For example, if two Users have the same date of birth, you can have multiple copies of an object that represents the date 16 Jan 1982.
- Factory: Used to create Entities. For example, you can use a Factory to create a Profile entity from a User entity.
- Repository: Used to store, retrieve and delete domain objects from different storage implementations. For example, you can use a Repository to store the Profile your Factory created.
- Service: When an operation does not conceptually belong to any object.
Maven Tutorial related articles
- Maven installation procedure for Windows
- Maven installation guide for Linux
- Maven release
- Maven compilation plugin tutorial
- Find unused jars using Maven
- Maven Dependency Tree
Sébastien Dante Ursini
17 Years of experience in Java
22 Year in Banking/Finance
Based in Geneva/Switzerland