In distributed applications, lookup and exception handling for remote business components can be complex. When applications use business components directly, application code must change to reflect changes in business component APIs.
These problems can be solved by introducing an intermediate class called a business delegate, which decouples business components from the code that uses them. The Business Delegate pattern manages the complexity of distributed component lookup and exception handling, and may adapt the business component interface to a simpler interface for use by views.
Core J2EETM Patterns
AdminRequestBD
handles distributed lookup and catches and adapts
exceptions in the sample application order processing
center (OPC).
AdminRequestBD business delegate manages
distributed component lookup and handles exceptions.
The structure diagram in Figure 1 shows the
ApplRequestProcessor servlet using
AdminRequestBD to find and use distributed
business components.
|
| Figure 1. AdminRequestBD locates and adapts other business components |
The code sample below shows the constructor for
AdminRequestBD. It uses class
ServiceLocator
to acquire the remote home interface of session facade
OPCAdminFacade
.
(See the
Service Locator
and
Session Facade
design patterns.) It uses the remote home interface to
create a
OPCAdminFacade remote component
interface, which it maintains in a private field.
The block that locates and creates the enterprise bean
reference catches exceptions related to finding the
home interface and to creating the component interface.
Any exception that occurs is then wrapped in an
AdminBDException
, which effectively hides the implementation
details of the business delegate from its clients.
public AdminRequestBD() throws AdminBDException {
try {
OPCAdminFacadeHome home = (OPCAdminFacadeHome) ServiceLocator.getInstance().getRemoteHome(OPC_ADMIN_NAME, OPCAdminFacadeHome.class);
opcAdminEJB = home.create();
} catch (ServiceLocatorException sle) {
throw new AdminBDException(sle.getMessage());
} catch (CreateException ce) {
throw new AdminBDException(ce.getMessage());
} catch (RemoteException re) {
throw new AdminBDException(re.getMessage());
}
}
AdminRequestBD for simple access to business components
components.
OPC servlet class
ApplRequestProcessor
receives service requests from the admin client in the
form of XML messages transmitted using HTTP. One of these
request is for statistics about orders that have a given status.
Method
ApplRequestProcessor.getOrders receives
part of an XML DOM tree representing a Web service request.
It extracts the status code from the document and
uses
AdminRequestBD.getOrdersByStatus to
retrieve a list of order information. The interface to that list
is transfer object interface
OrdersTO
.
(See the
Transfer
Object pattern.) The code in the request processor
that retrieves the order information appears in the following code
sample.
public class ApplRequestProcessor extends HttpServlet {
...
String getOrders(Element root) {
try {
AdminRequestBD bd = new AdminRequestBD();
NodeList nl = root.getElementsByTagName("Status");
String status = getValue(nl.item(0));
OrdersTO orders = bd.getOrdersByStatus(status);
...
}
Because it has already created the reference to an
OPCAdminFacadeEJB, the
AdminRequestBD object can
simply forward the call to the enterprise bean's method
getOrdersByStatus, as follows:
public class AdminRequestBD {
...
public OrdersTO getOrdersByStatus(String status)
throws AdminBDException {
try {
return opcAdminEJB.getOrdersByStatus(status);
} catch (RemoteException re) {
throw new AdminBDException(re.getMessage());
} catch (OPCAdminFacadeException oafee) {
throw new AdminBDException(oafee.getMessage());
}
}
...
}
Notice again that the method catches any exceptions that the enterprise bean may throw and re-throws an exception type that is specific to the business delegate's interface. This hides the business delegate's implementation details from the client.