Eric Pugh wrote:

Hi all,

Over the past 6 months I have been really getting into the COP approach.
Starting with Excaliber, a brief foray over to XWork, and now the porting of
Turbine and Fulcrum to Merlin.  And over the past month's I have had to
explain repeatedly why I am interested in using a container and components
in my applications.

Sorry, I didn't want to ignore your message, but more info down low.


And of course, the number one complaint/concern:  "I don't want to implement
somebodies interfaces..  Isn't that like EJB?"  To which I typically respond
that implementing a Startable/Stoppable/Configurable interface is no
different then what you would be doing anyway if you needed that
functionality.  And you are implementing well understood, widespread
interfaces.  Especially the Startable/Stoppable interfaces, that makes
complete sense.  Some people people do point out that instead of a
Configurable interface, they would set a series of javabean properties.  To
which I respond that eventually, if you have too many, you end up with a
config object, so you might as well start out with Configurable.  And you
can always do it by hand via JavaBeans.  And this satifies most people..

To tell the truth, alot of this complaint line falls under stylistic differences. I prefer to do JavaBean style components, or I NIH (Not Invented Here) syndrome. The thing about the interfaces is that you don't *have* to implement any of them. They just add some nice features that help make writing the component easier.

Even how you obtain your services can fall under this approach.

It is a far cry from EJBs because EJBs force you to implement an interface
that mixes several concerns so your component has several empty methods, and
write a "key" object, and write a static "Home" class.


Which brings me to the one thing people really don't get..   Why do I have
to implement Serviceable to get a hook into other components?  Why can't the
container just give me the components?  I mean, in my java code inside the
component I have to pick what I want.  Why not define it outside and have
the container set it?  And I get all balled up in explanations..  Of which I
can think of many, like at run time I can pick and choose my components I
need..  If I have setting X, I get component X.  If I have setting Y, I get
component Y.  However, this did kinda make me wonder...   Why can't I just
expose the components I need and provide a setter?  Most of the time, I
always want an instance of component X.  In fact, often, because of unit
testing, if I have a dependency on component Y, then I just provide a
setter, so that at unit test time I can pass in my MockY component, versus
having to use a custom test configuration loaded through avalon.

What is the difference between the ServiceManager and JNDI, other than the fact that it is a much lighter weight thing?

Many of these people can understand the use of JNDI, but they don't like the
ServiceManager because they have their own pet way of doing things.

That said, there are always valid points in every point of view.  Many times
it is a balance that must be struck for each project.  For example, systems
that are simple enough to have one instance of a component would be easier to
write if the component were passed in through a setter.  Systems that require
dynamically managed components where an instance can be disposed of and replaced
dynamically have a different set of requirements--hense they need a lookup
mechanism.

To be fair the ComponentManager/ServiceManager concept was cooked up way back
before J2EE and EJBs.  We discussed adopting JNDI, but at the time there were
disagreements over how to look up items bound to JNDI.  Would "Context" items,
"Configuration" values, and "Services" all be bound in there?

Avalon was born as a server side component framework, but it is perfectly
comfortable on the desktop as well.  Implementing a ServiceManager is very much
easier than implementing a JNDI service provider.

The idea of using setters as a way to provide components is a very new concept.
Personally, I don't like the approach because of the systems that I have had
to maintain that were done with static accessors all over the place and other
major set backs.  So my bias is based completely on those negative experiences.
I recognize that, and I see value in the setter approach as long as all your
components are set once.

The ServiceManager has the concept of a defined set of time that a client has
a hold of a component.  You lookup() and release() components.  This approach
has the advantage of letting the container know without a doubt when it is safe
to upgrade a component.  It gets us philisophically closer to the 0 downtime system.

With a setter based system, you don't have those contracts, so the only safe
thing is code for write-once.  Which also means that you have to take special
care to manage concurrency issues and balance the synchronization vs. stability
within the system.

Imagine if you had a component like this:

EmailManager {
    void logIn(String user, String password);
    Message[] getMessages();
    void sendMessage( Message message );
    void deleteMessage( Message message );
    void logOut();
}

This component makes certain assumptions about the order the methods will be
called.  Now, let's assume that we don't have any synchronization issues to
worry about.  If at any time the container chooses to update the component
implementation, we run the risk that it will be done in the middle of using
it.  For instance, we may have logged in, obtained our messages, and then
the server upgrades the component with the setEmailManager().  Not only have
we not logged out with the old component, we aren't logged in with the new
component.  When we call sendMessage() or deleteMessage() next, we will be
in an unknown state.

That at least is the argument against the setters.  Many systems are not that
complex, and make many assumptions about the type of environment that the
application will be run in.  For instance, one assumption is one user, one
thread, unchanging components.  In this case, whatever you choose is a matter
of personal taste.

If there is any potential for your system to grow into a mult-user,
multi-threaded, dynamic system--the setter approach will become a hindrance.
In fact there will need to be more esoteric magic that has to be performed
to maintain the health of the system.  The lookup approach of either
ServiceManager or JNDI will be easier to handle these demanding requirements.
JNDI doesn't make sense for smaller systems or embedded systems--so the
happy medium we have is the ServiceManager.

It is neither right nor wrong, it is just the solution we have come up with.
We are looking to make things work with other folk's component types such
as Nano/Pico/Spring container type components.  It is very possible to do
with the existing modern Avalon containers.  We just don't have a nice generic
way of incorporating those features.

<snip/>

On a related note..  If you had this facade (?)/interface layer, then the
various Activity lifecyle interfaces wouldn't need to be implmented.  I
could instead provide a mapping file that said: For my component, I do
implement the Startable interface, I just didn't implement it, and my method
is called "begin()".  This would work for noarg methods especially well.
Actually, I guess would this be a proxy?

This component proxy you are talking about is also a nice way to incorporate interceptors which make it easier to add new functionality to all components in the system.

--

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


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to