axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Berin Loritsch <blorit...@apache.org>
Subject Re: [Architecture Improvement] Handler lifecycle events and undo()
Date Fri, 14 Dec 2001 19:35:43 GMT
Sanjiva Weerawarana wrote:

> I'd like to see this taken further. Using your own argument Glynn,
> has anyone given a "*real*, non-fictional example" or where any
> of init()/destroy()/undo() is useful? If so keep them all (rename
> or do whatever; I don't care).
> 
> If not, YAGNI.


Since we are talking about Lifecycle and Architecture, I have to pipe up ;P

It is very important that architecture be consistent, and that the
method names be accurately named.  This reduces the learning curve.

Here is what the Avalon team has learned in respect to Lifecycle:

1) Not every component will need every lifecycle interface
2) A collection of components will more than likely need all lifecycle
    interfaces.  While it is rare for one component to use all of them,
    when you have a number of Components with different needs, each will
    use a different set--and eventually all lifecycle methods are needed.
3) Event based systems scale better than monolithic ones (i.e. SAX vs.
    DOM, non-blocking vs. blocking IO, event based architecture vs.
    thread per client architecture).

In order to address this, the Avalon team developed a set of interfaces
that handle different aspects of the lifecycle.  The lifecycle follows
a well defined path so as not to confuse people unnecessarily.

Many components have *real* needs to prepare itself before it can be
used.  Again, many components have real needs to release resources
when the component is no longer needed.  The Avalon interfaces for
these are Initializable and Disposable, and each have one method:

Initializable.initialize() throws Exception;
Disposable.dispose();

For instance, a Handler may have lookup data that it needs to obtain
outside of itself, and cannot get a reference to the required component
during construction.  This is quite common in environments that enforce
Inversion of Control.  Again, that lookup data will have to be released
properly when the Handler is no longer needed.

Regarding undo(), it is improperly named--but the concept is quite
necessary.  It is for transactional services.  If the service failed,
the handler needs to clean up resources from the transaction.  This does
not mean that the component/handler needs to release all resources--just
the ones from this transaction.

However, transactional services do require a more traditional commit/abort
cycle.

Getting back to the init()/destroy()/delete() functionality issues, it
is incorrect to force _all_ Handlers to define them.  A Handler's interface
should only support the methods required to *Handle* a request.  All other
methods that are sometimes required should be placed in other interfaces.

This approach allows the developer to separate the concern areas of his
specific handler.  The simplest Handlers will merely process information
on the fly with no lookup information required for operation.  More complex
handlers can add functionality as needed.  While this does add a little more
complexity to the Container for the Handlers, the complexity is easily
managed.  For example, with the three point "lifecycle" that Handlers have
hardcoded, during initialization, the Container tests all the Handlers if
they implement the Initializable interface and call the appropriate
method as needed.  During run time, all the Handlers are treated identically.
During tear down, the same idea happens with the Disposable interface
as what happened with the Initializable one.

This separation of concerns simplifies the system for the Handler writer.




It is something to consider....

-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


Mime
View raw message