[ Pobierz całość w formacie PDF ]
Note that the choice of using the home interface class as a mechanism for
requesting a home is an implementation decision designed to simplify the
client and factory, but it is not necessary. You could easily change the lookup
method to take in a class and a JNDI name, as follows:
AccountHome accountHome = (AccountHome)EJBHomeFactory.getFactory()
.lookUpHome( AccountHome , AccountHome.class);
The disadvantage of this approach is that the client is burdened with the
hard-coded JNDI names of the homes that need to be looked up, which dimin-
ishes the maintenance benefits of the EJBHomeFactory pattern.
Client-Side EJB Interaction Patterns 97
A SERVLET-CENTRIC ALTERNATIVE
A common practice among servlet developers is to place EJB home
initialization logic in Servlet.init(), and cache EJB homes in the ServletContext
object, since it is shared across the application. This approach shares the same
benefits as EJB home factory (performance, simplicity), but complicates code a
bit more. Common presentation layer constructs such as Java bean helpers
do not have access to the ServletContext, and would have to be manually
passed one in, in order to get access to an EJB home. Since the home factory is
a singleton, it can exist anywhere in your Web application and can thus
simplify your code.
The EJBHomeFactory pattern is a simple and efficient way to abstract EJB-
Home lookup complexity from the client in a completely generic, reusable
format. By caching EJBHomes, performance is increased significantly by elim-
inating costly redundant home lookups. The EJBHomeFactory provides a con-
sistent interface to home object lookup, and is reusable in any environment
(applet, servlet, standalone, even in between EJBs).
Related Patterns
Service Locator (Alur, et al., 2001)
Factory (Gamma, et al., 1995)
98 Chapter Four
Business Delegate
When using session and/or message façade, the client is tightly coupled to the
EJB layer, creating dependencies between client and server that affect devel-
opment, run-time, and project management concerns.
How can an intermediary between a client and the session façade be
created to facilitate decoupling the client from the EJB layer?
* * *
In a good EJB design, use cases should be divided up over a layer of session
and/or message-driven beans, as described in the Session and Message
Façade patterns, respectively. A common way to interact with this layer is via
direct invocation from client code. That is, your presentation layer will directly
interact with EJBHomes, and EJBObjects for session beans, and send JMS mes-
sages when talking to message-driven beans.
Ironically, programming directly to the EJB APIs is not always the best way to
program EJB applications. Various issues can arise, all of which revolve around
the problems created by tightly coupling the client layer to the EJB layer:
Reduces separation of roles between client programmers and server
programmers. On large projects, speed and efficient project completion
depend upon the ability of the client tier (that is, servlet/JSP) developers
and the server-side EJB developers to work independently. One com-
mon dependency that can arise between teams is the availability of the
complete and compiled session bean layer. Client programmers depend
on the implementation of the session façade in order to compile and test
their code, creating a terrible bottleneck between the two teams.
Places optimistic concurrency recovery responsibility on clients.
Often a transaction will fail due to an optimistic concurrency conflict at
the application server or database level, catchable by the client as Trans-
actionRolledBackException or TransactionRolledBackLocalException.
For certain types of use cases (such as idempotent operations), it may
not be necessary to propagate this error down to the end application
users and ask them to retry (usually by clicking submit again on a Web
form). Instead, client code should automatically reexecute the transac-
tion. When coding directly to the EJB APIs, client code needs to explic-
itly catch these exections and retry the transaction, which places a large
responsibility on the client developer (who may not fully understand
the nature of the use case implementation, since they didn t write the
EJB layer), as well as cluttering up their code.
Client-Side EJB Interaction Patterns 99
Complicates client logic with complex error handling. Clients need
to be burdened with the ability to catch and react to the myriad number
of errors that can occur when looking up and using EJBs, including
exceptions thrown when looking up components, RemoteExceptions,
EJBException (when using local interfaces), and so on. Remote or
EJBExceptions in particular can occur for a variety of different reasons
(such as optimistic concurrency conflicts described above), placing the
responsibility on the client to implement messy code required to parse
an exception and determine how to react to it.
Couples the clients directly to EJB and JMS APIs. Even when execut-
ing simple use cases, clients need to be loaded with EJB- or JMS-
specific code required to discover, create, execute, and recover from
[ Pobierz całość w formacie PDF ]