Spring-based architectural approach
We'll reproduce conclusions from a thread opened in Spring user-list (Spring experiences revealed) last week
The goal is to help new spring-based developers with little background in J2EE best-practices. Here's our architectural approach for a still in progress application required by an F&I company
Architecture considers three layers: Presentation, Business and Integration
Presentation deals with navigation control (input validation, etc) and protocol-based compliancies (HTTP, XML, rich clients)
Business layer concentrates exclusively domain logic. It offers business services to Presentation layer by interchanging business objects
Integration layer has to do with external application interoperatibility. This layer offers such kind of extra services to the Business layer
Now let's see in more detail roles involved in every layer
Presentation Layer aggregates Controllers and Forms
Controllers are relatively organized in a "one-per-use case" fashion (except some few reusable cases). Spring's web controllers (see org.springframework.web.servlet.mvc package) are a fast and helpful set (we recommend AbstractWizardFormController for highly interactive use cases). Spring's form controllers consider validation as strategies (Strategy pattern)
Forms are POJO versions of HTML forms. Spring helps hide Form creation by formBackingObject property specification. Spring also helps during binding among HTTP parameters and Form's field
Thus, Controllers handle navigation and invoke services offered by Business layer in order to advance to next stage (such invocations normally takes place in processFormSubmission() or referenceData() Controller's methods)
Business layer exposes Business Managers as facades relatively organized in a "one por application module" fashion. Thus, ProductInventory, SalesManager, etc are good candidates to play such role
Business Manager behavior is very similar to Controller behavior. The only difference is the context they are playing their roles. While Business Managers deal most of time with business objects and other business specific data, Controllers battle with input requests and presentable responses
Business Managers carry out their services by activating one or more Business Objects. Business Objects are domain model elements such as Account, Order, Car, OrderLineItem. They don't be merely limited to expose properties (i.e. getters and setters) without any further behaviour
Business Objects should be capable to perform its own domain logic, even "talking" with other Business Objects (structurally associated or passed as input parameters). We find developers encounter this point a little confussing, wrongly considering, for instance, that Business Objects should see Business Manager in the same way Business Managers see Business Objects
Our point is that Business Objects compose a sub layer with data and behavior but no visibility about other layers. A Customer, let's say "John Doe"s, simply exists. He should never ask to database to retrieve his own record. Such kind of job should be done in Integration layer (as we shall see next) upon a Business Manager request
To finish our discussion about Business Objects, they should help to avoid unnecessary creation of Transfer Objects (aka known as Data Transfer Object and Value Objects when immutable). So, Business Objects should be their own Transfer Objects, traversing three main architectural layers: they can't see nothing but themselves, but everybody can see them
Integration layer exposes "one-step beyond" services to Business Managers. Mostly considered as a Persistence layer, we'd rather see this layer as Integration layer in the sense of interoperatibility with third party facilities, being persistence a special case only. Other examples consider transactional systems (CICS/VTAM), legacy applications or even real time system which main purposes not merely related with data persistence. In many cases they are "the" real applications, leaving our application simply as a sophisticated value-added front-end (SOA)
A goal that cannot be waived in this layer is to isolate Business layer from specific interoperatibility details. We should never return neither a ResultSet, nor a received XML document, neither a java.nio.ByteBuffer nor any kind of specific implementation technology subject to possible replacements. Who doesn't take into account this proverbial principle could be subject to replace the whole application sonner than later (honestly I would replace quickly such kind of "pragmatic" persons)
Unfortunately most of "so-considered" MVC Model-2 applications, in practice don't respect that premise
To Business Layer should return Business Object most of time. Maybe Transfer Objects in some considerable cases
Most popular pattern of this layer is DAO Pattern. Not usually mentioned but even important is classic POSA Broker and all his revisions and reimplementations
Spring provides here helpful tools in order to lighten specific aspects while accesing record-oriented storage. Please take a look of JDBC support in org.springframework.jdbc.object package. Spring efforts to easily integrate tools for O/R mapping are remarkable. In our application we are using hibernate-based dao support provided by org.springframework.orm.hibernate.support.Hibernat eDaoSupport. O/R mapping tools are fundamental to avoid unnecesary and even expensive Transfer Objects proliferation to Business Layer. The choice is up to you
To finish, I want to make a close revision of previous depicted role instances
Presentation layer: one only Controller instance for each Controller class (at least, for each Controller bean declared in Spring's BeanFactories configuration files)
One Form instance for every HTTP request execution of its corresponding Controller
Business layer: one Business Manager for each facade bean declared in Spring's config files
We couldn't predict how many Business Object instances could be alive in a certain moment. Remember a Business Object instance plays the role of its own transfer object, so the life cycle of a Business Object instance could go beyond its creator service execution
Integration layer: one instance for every DAO and other layer service provider declared in Spring config files
As a conclusion, our Business layer dont't have neither J2EE nor open-source API's imports. Only basic J2SE API's imports and also our own Business and Integration layer interfases
We have based our architectural implementation on current readings. I can suggest:
-"Expert one-on-one J2EE Design and Development", R Johnson. Wiley, 2003
-"Expert one-on-one J2EE Development without EJB", R Johnson, J Hoeller. Wiley, 2004
-"Wiring Your Web Application with Open Source Java", M Eagle. http://www.onjava.com/pub/a/onjava/2...ngwebapps.html, 2004
-"Pattern-oriented Software Architecture, Vol 1", F Buschmann et al. Wiley, 1996
-"Enterprise Integration Patterns", G Hohpe, B Woolf. Addison-Wesley, 2004
Diego Dagum
Self-confidence, Chile