Thinking Architecture/Design

Sunday, December 20, 2009

UI Concerns



  • This blog will explains the UI concerns mentioned below and their possible ways to tackle them

  1. Validations
    1. How to capture validations?
    2. When to apply validations?
    3. How to reuse validations at different layers?
  2. Interactions of UI based services with middle tier services like Crud, Search services
  3. Transaction boundaries.

The below picture depicts architrave/design which takes into consideration the above-mentioned concerns.

























Context
The central to above design is a notion of context. What is context?
A context is an object that captures the basic criteria that gets passed in a request.
Contexts are recursive. There can be multiple sub-contexts attached to a context. A Context can be defined as


public class Context implements Iterable, ServiceIdentity {
// Captures searching information. This can be JPA 2.0 Criteria Query
SearchCriteria searchCriteria;
// Captures pagination information i.e. rows to be displayed in the UI page
PageInput pageInput;
// Sorting information
SortCriteria sortCriteria;
// Bean-util friendly and can be used for scripting access to specific //parameters in both request and response.
Map request;
Map response;
}

A generic service often behaves differently depending on what context is passed to it. Hence it becomes difficult to determine the intent of the service based only by its interface or implementation class. ServiceIdentity interface standardizes this convention. By implementing this interface a Context object announces what the intent of the service class should be for this specific context. This is also useful for implementing many horizontal services such as security, logging etc.

So the ServiceIdentity looks like

public interface ServiceIdentity {
public abstract String getService();
public abstract String getOperation();
}

ServiceFascade

This fascade layer, that passes the context to the underlying midlle tier using orachestrator. The contract of the ServiceFascade is as follows

public interface ServiceFacade {
public Context process(Context context) ;
}

Orchestrator

The Orchestration would be based out of similar frameworks such as xwork and Commons Chain.This would however improve on the features provided by both of those frameworks and is designed to be extremely extensible and dependency injectable. This framework will enable the implementation of Chain Of Responsibility design pattern by orchestrating beans defined in the spring container.

NOTE :-  Apache Commons chain could also be used but it's not that spring friendly and does not has in built capabilities for orchestration of beans in the spring container.


Validation Module (VM)
Any Validation framework should provides ability to write rules under the following classification

  • Business Policies – e.g. Spending Policies, Approval Matrices  
  • Constraints – e.g. db constraints,Valid configurations, regulatory requirements   
  • Computations – e.g. Discounts, Premiums, Scores   
  • Reasoning Capabilities – e.g. Offers based on customer value

NOTE :- Normally most of the framework, provide ability to write Constraints rule.

The validation module is equivalent to pojo class responsible for validation. Following the DRY (Don't Repeat Yourself) principle, validation framework provides ability to express domain constraints once (and only once) and ensure their compliance at various layers of the framework. Annotations are a very convenient and elegant way to specify invariant constraints on the domain model implementation, the persistent classes. Validation framework provides following annotations: -
  1. BusinessRule:- Fundamental unit of validation framework is BusinessRule.BusinessRule is an annotation that can be applied on the JPA entity & will be fired on db operation – Create/Update/Delete.            
       @BusinessRule(name = "myRules",rulesBefore = "dynamicFieldUsage.inLov : ? = TRUE : 'Indication lov
                                 is not True' : 'errors.indInLov'"}
       @BusinessRule(name = "myRules",validators={V1.class,V2.class}}
        public class xxxEntity 
    2. BusinessRulesChain is an aggregation of  BusinessRule

       @BusinessRulesChain(name="personBusinessRules",valdationDecider=ValidationDecider.class,
          BusinessRules={
         @BusinessRule(name="personObjectValidation1", validators={PersonObjValidation1.class}),
         @BusinessRule(name="personObjectValidation2", validators={PersonObjValidation2.class}),                                      
          })
     public class PersionService



The validation module or validator contract is as follow
public interface Validation {
     public void support(class klass);
     public void validate(Object target,Errors errors)
}


NOTE :- 

  1. For simplicity reason the above contract is same as spring beans validation contract.
  2. The above rules classifications can be implemented using rules engine like jboss rules etc etc (The above is java based approach)
   Hence in nutshell the validations can be classified into two types

  • Entity Level Validations:- The life cycle of these validations are shown below


  • Service Level Validations:- The life cycle of service level validations is shown below



Key Features

  1. Validation modules (annotations) are inheritable hence all the validation in the inheritance chain will be fired automatically
  2. Validation modules are automatically triggered based on object changes in the currently executing transaction (session).
  3. Validation module integrates seamlessly with valang
  4. Validation modules when specified as chain executes in order in which there are specified.
  5. Validation modules when specified as chain, then specifying ValidationDecider can control the execution of validation module
  6. Validation modules are based on JSR 303 and JPA 2.0 bean validation specification.

NOTE :- The above was extension to Hibernate/Eclipselink JPA 2.0 validation framework but with few limitation like automatic rule chain firing, Hibernate/EclipseLink JPA 2.0 could also be used directly.


The entity level validation modules can be parsed at container start time (like using spring bean post processor) and fired from the application Crud DAO/Service  (using AOP). Similarly validation module specified in the service layer are injected (as prototype bean). The injection mechanism is automated for example by using spring bean post processor.


Transaction Boundaries
Since UI model calls setter/getter method outside the transactional boundaries as result those changes are *NOT* visible. This can be tackled by detaching the session (hibernate/eclipselink session) and then attaching it back, inside the transactional boundaries (join the transaction)

NOTE :- Transaction boundaries can be defined either using Spring's declarative transactions or EJB stateless session. The latter will require container for unit testing.

Conclusion

The above blog shows flexible design of the UI interaction with middle tier by addressing concerns like transaction, validation etc. This design will also enable testing of each components/services separately. As the domain model passes through different layer of architecture and validation concerns are different across different layer; the above design provide the ability to apply validation modules in very flexible way in any layer.

About Me

We are Senior Java Architect expertise in JEE + JEE Open source. We love making JEE framework. We think and breathe java and love discussing on it.