In one of my recent projects, during finalizing the technology stake for a new web application, I got to a situation where I needed to decide the integration strategy between different layers including web and business service layer. The key point to decide here is whether to use the smooth and out-of-the-box integration mechanism provided by the frameworks or use standard J2EE design pattern for framework agnostic integration.
To be specific, we were using Struts 1.3 (I love the simplicity of Struts 1.x MVC framework, apart from all other reasons why we selected it) at web tier, and Spring IoC at business service tear. And the decision to make is whether to use the Spring supported integration with Struts framework (using ContextLoaderPlugIn, extending ActionSupport class, using DelegatingRequestProcessor etc) OR using Business Delegate pattern to completely separate the two layers.
The below 2 diagrams further depicts the 2 possible scenarios.
In other words, we had the option of either using Spring support for Struts (using ContextLoader plugin, extend to Actionsupport class etc). The Spring’s Actionsupport class provides easy-to-use methods to get the Spring IOC’s context to get access to service beans. OR we use Business Delegate pattern, in which a separation layer will be introduced between web and service layer. This layer will delegate calls to service layer and provide abstraction. Also, the task of locating the services can be handed over to service locator.
Here is the list of advantages and cons with each of these approaches.Using Spring provided smooth integration approach
1. It provides an easy mechanism of integration. The Spring provided ActionSupport class provides an easy way to get the Spring beans, through web context.
2. Being a direct communication between web and business service tier, it doesn’t involve other layers and hence a bit advantageous from performance perspective.
3. The biggest issue with this approach is tight coupling between the 2 layers. Web tier not only knows about the business service tier but also has information about with what name the bean is registered and how to get handle of the bean.
4. Another issue being that the service tier has direct exposure to web tier and hence web tier knows each core business service. This may result in multiple network calls from web to service tier.
5. Practically, it would be difficult to deploy web and service tier in distributed manner.
Using Business Delegate Pattern
1. The web and service tiers are loosely coupled and separated by business delegate layer.
2. Business delegate pattern provides abstraction over the core business services. For e.g. to accomplish a particular task, business delegate may need to call multiple services but web tier needs to call a single method on delegate. In other words, orchestration of services can be accomplished in much better manner with business delegate pattern.
3. Business exceptions can be handled more efficiently at delegate layer.
4. The services are located using service locator, which is the only entity has knowledge as where and how services are registered and deployed. This could be very useful in case of distributed environment.
5. The only drawback is to have additional layer (delegate) and service locator entity in the architecture.
Finally we decided to adopt the 2nd approach, using business delegate pattern and results were quite satisfactory.
Conclusion: Spring provides direct integration with different web frameworks, but to choose it or adopt business delegate pattern, should be pondered well in the given situation. Loose coupling, separation of concerns and abstraction, would always be helpful in long run.