|
We had an
interesting discussion at work about design patterns and EJB Home
interface was used as an example of the Factory Method pattern as
defined in the GoF book. I have heard this before. Upon googling, I
found more places where EJB Home interface is used as the example of
the Factory Method pattern. See here,
here
and here.
The factory method
UML diagram is shown below.
The explanation
typically given is, "home interface provides methods to create bean
instances" or "EJB home interface, which creates new EJBObjects"
or "XxxHome creates instances of Xxx and YyyHome creates instances
of Yyy." This is incomplete and even inaccurate explanation of the
Factory Method pattern.
To make my point, I
turn to the design pattern bible - the GoF book. The book clearly
says, "Use the Factory Method pattern when, a
class wants its subclasses to specify the objects it creates."
It is easy to think that in case of EJB Home, javax.ejb.EJBHome wants
its subclass (say) AccountHome to specify the objects (say)
AccountRemote it creates.
So far so good.
However, as shown in the figure above, the factory method is defined
by the abstract super class or interface and implemented by the
subclass. In case of EJBHome, it does NOT define any create methods
for its subclasses to implement. See for yourself here.
Create method is a 'special' method defined by the J2EE specification
as a means to return an implementation of the business interface.
There is also
another issue.
The figure above
shows multiple subclasses that provide factory methods. They all
create objects of type Figure (LineFigure or TextFigure). When you
apply this concept to EJBHome interface, multiple subclasses such as
AccountHome and OrderHome do NOT create objects of the same super
type. AccountHome creates AccountRemote and OrderHome creates
OrderRemote. These business interfaces don't implement the same
contract.
The correct explanation
With
EJB home interfaces, factory method is used when the 'container'
implements the interface.
When
you define the AccountHome interface, you don't know how to create
the objects that implement Account business interface. So, you leave
it up to the subclass or the implementation of your interface to
decide how to create those objects. You define a factory method and
let the implementation provide the method. When you deploy your bean
in a 'different container,' you may have Container2AccountHome that
implements the factory method create () and creates Container2Account
classes when invoked by the client. In yet another container, you may
have Container3AccountHome and so on.
In
case of the home interface example of the Factory Method Pattern, you
will NOT have a situation shown in the second figure (Figure and
Manipulator classes) above.
|