Browse DevX
Sign up for e-mail newsletters from DevX


The COR Pattern Puts Your J2EE Development on the Fast Track : Page 4

Find out how the "Chain Of Responsibility" pattern can rein in your beans and facades to meet evolving business requirements. Route client requests transparently to EJB server components without hardwiring client/server interactions or worrying about low-level plumbing issues.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Step 5. Write Your Business Logic Service Implementors
Service class implementors are simple POJOS that either perform business logic directly or act as proxies for other Java classes or Local/Remote Session Beans. Either way, your service implementation is responsible for deciding which commands it handles and which it does not. If you're delegating to a Remote Bean, be sure to check whether the command can be processed prior to forwarding it. This preempts any unnecessary remote calls. Ignore any unknown commands by returning null to the COR Manager.

Create two services:

  1. A simple Echo Service responsible for echoing commands back
  2. A View Service responsible for satisfying ViewCommand query requests

Service 1. An Echo Service:

public class EchoService implements Service { /** * Constructor for EchoService. */ public EchoService() { } public Command process(Command command) throws ServiceException { return command; } }

Service 2. A View Service:

public class ViewService implements Service { /** * Constructor for ViewService. */ public ViewService() { super (); } /** * Process the command. If it is a ViewCommand query the DBMS * and return the results inside the command. */ public Command process(Command command) throws ServiceException { if (!command.getClass().equals(ViewCommand.class)) { return null; } // process view command ViewCommand vcmd = (ViewCommand) command; try { // Get your SQL DAO SQLDAO dao = SQLDAO.get(); // Issue Query List result = dao.executeQuery(vcmd.getDescriptor()); // set results back into the command sb vcmd.setResult(result); } catch (DAOException de) { throw new ServiceException(de); } return vcmd; } }

The COR Manager will create your Service implementors when it starts up. Ensure that your classes can be dynamically class loaded by providing an appropriate default constructor to perform any service initialization work.

Step 6. Configure Your COR Manager Instances
The final step to setup the COR Manager is to configure a COR Manager instance with the Echo and View Services. Drive this from a configuration file. Set up a common COR manager instance and add the services to the manager's service chain. Put the View Service first in the chain and the Echo Service last to ensure that commands will be passed through the view service. This gives the view service an opportunity to process before it finally ends up at the Echo Service, which applies the default behavior by echoing the command back to the caller:

# The Default COR Manager CORManager.default=common # The Common COR Mgr common.services=ViewService,DefaultService # Service Class Providers ViewService.classname=au.com.ldabreo.services.view.ViewService DefaultService.classname=au.com.ldabreo.services.chain.EchoService

Adding more services is simply a matter of writing the service class and adding it to a service chain in the configuration file for your COR Manager instance. No change is required at the client level, as the service automatically gets included as part of the COR routing behavior.

Balancing Your Service Chains
Group services that are alike under the same COR Manager instance. Structure your groups so that you minimize your service chains. This becomes a trade-off between performance and flexibility. The most flexible approach is to centralize your services under one COR manager. This gives every service a chance to process the request. The least flexible but most efficient approach is to divvy up your services logically among your COR Manager instances.

Step 7. Execute Your Command!
To use the COR framework, create a command instance and pass it to the COR Manager to process. In this case, exercise the ViewService by using the ViewCommand. Set the isTransactional() flag to false since the query does not require a transaction and may be executed locally:

ViewCommand command = new ViewCommand(ViewDefnFactory.get().createViewDefn(
"au.com.ldabreo.services.examples.views","myview")); command.setIsTransactional(false); // Send to COR command = (ViewCommand) CORManager.get().process(command); // Process results Object[] rows = command.getView(); for (int i = 0; i < rows.length; ++i) { System.out.println("Row(" + i + ") " + rows[i]); }

If you've set up your COR correctly, the ViewService will handle the ViewCommand and pass back the query results.

COR Trade-offs
The COR pattern illustrated in this article gives clear benefits in terms of clean separation between client/server tiers, centralized run-time transaction control, good encapsulation of server functions, and inherent extensibility. It enables business logic to be handled independently of the request, and it minimizes the impact of change. New components may be added easily without having to modify or add new client/server interfacing code. Components are free to collaborate outside packaging dependency restrictions. With transaction control in place, business functions may be quickly leveraged without having to write Session Beans. This means fewer beans (with their associated performance and deployment overheads) and faster development turnaround times. You can always add Locale and Remote components later, so as to support your target deployment architecture.

However, all patterns have their downsides. The COR pattern does not give constant time response, nor is it as type-safe as a Session Facade. Finer-grained deployment/transaction control behavior must be added into your business components as required. That said, the COR pattern, used wisely, can be a powerful enabling framework for facilitating fast growth, ease of development/deployment, as well as for reining in your J2EE bean/facade bloat.

Lara D'Abreo is an independent consultant with over 10 years experience in commercial product development in the US, Japan, and the UK. She's currently based out of Sydney, Australia and spends her time trying to make J2EE systems run faster.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date