avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stephen McConnell <mcconn...@apache.org>
Subject Re: Alternative to Serviceable interface?
Date Tue, 04 Nov 2003 23:41:49 GMT


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.
>
>And most of the ususual reasons make sense to people.  The easy
>configuration of components.  The reliance on the container to start things
>up in the correct order, etc..
>
>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..
>

Just a point concerning "I don't want to implement somebodies interfaces.."

I think this is a totally valid concern.  As soon as you implement 
someones interface you create a dependence on the interface which means 
a dependence on the package which means a dependence on the project 
which means a dependence on that community.

Instead - we can look at the container <--> component contract with a 
little more flexibility and say - ok - what is you strategy for 
configuration?  We (Avalon) can provide a default strategy using the 
Configurable interface and Configuration artifact - and if you don't 
like that, then you can declare an alternative strategy using your own 
lifecycle stage handlers.  What this means is that a developer can 
eliminate any Avalon dependency from the component, providing the same 
developer provides a set of custom handlers.  This means that the 
developer completely isolates the component model contractual dependency 
to a small number of custom extensions.  Its more work for the developer 
- but in some cases its justified.

All of this is possible today.

>
>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.
>
>I looked at the /tutorial/composition/application/impl/../Application.java
>class, and it does precisily what I want it to do..  It implements
>Serviceable, and it looks up objects named "locator" and "publisher".
>Admittedly, in the example, it then does something, but for my purposes, I
>would be happy to just know that when I loaded up the Application component
>I had a locator and publisher objects.  Now, both of these objects were
>defined for me in my block.xml:
>
>     <include name="location" id="merlin-tutorial:locator-impl"
>version="1.0"/>
>     <include name="publisher" id="merlin-tutorial:publisher-impl"
>version="1.0"/>
>
>Including all the info to resolve them!  So, what would be involved in
>having a something that did the servicable for me?  If Application.java has
>a setLocation() and setPublisher() methods, and something was set in the
>block.xml, then Application.java could skip the serviceable method and
>Merlin could just populate the setters for me.  In the XML below, I just
>added an autoset="true" to the component declaration that would be the key
>to Merlin to just create the darn objects and pass them in...
>
><container name="application">
>     <classloader>
>       <classpath>
>         <repository>
>           <resource id="avalon-framework:avalon-framework-api"
>version="4.1.5"/>
>           <resource id="avalon-framework:avalon-framework-impl"
>version="4.1.5"/>
>           <resource id="merlin-tutorial:locator-api" version="1.0"/>
>           <resource id="merlin-tutorial:publisher-api" version="1.0"/>
>           <resource id="merlin-tutorial:application-impl" version="1.0"/>
>         </repository>
>       </classpath>
>     </classloader>
>
>     <include name="location" id="merlin-tutorial:locator-impl"
>version="1.0" />
>     <include name="publisher" id="merlin-tutorial:publisher-impl"
>version="1.0"/>
>
>     <component name="application"
>        class="tutorial.application.Application" autoset="true">
>     </component>
>
></container>
>
>I can see issues where location maybe wanted some other objects as well.
>However, those dependencis could be setup in here to, correct?  Via more
><component> tags?
>
>The reason I bring this up is because I have been reviewing, under prodding,
>other frameworks.  The nice thing about the SpringFramework is that your
>components don't have to implement interfaces (other then a
>startable/stoppable one) to be used in Spring.  And they don't have to
>implement a Serviceable type interface.
>

What you describing is an alternative strategy for the assignment of
services to a component.  Lets' forget about meta-data directive like 
autoset,
but instead think about how to declare an alternative assignment 
strategy at
the level of a component type. 

E.g.:

  /**
   * Assignment of the service by the container.
   * @avalon.dependency
   */
   public void setRabbitWarren( RabbitWarren warren )
   {
       m_warren = warren;
   }

It seems to me that there is sufficient information for a container to
resolve this.

>I think having Serviceable is very good in some situations.  But, in many,
>it is overkill.  I just want to get a component, and have the X dependent
>component already loaded, versus having to everytime do this:
>
>        LocationService locator = null;
>        Object object = manager.lookup( "locator" );
>        if( object instanceof LocationService )
>        {
>            locator = (LocationService) object;
>        }
>        else
>        {
>            final String error =
>              "Object " + object.getClass().getName()
>              + " does not implement the LocatorService class.";
>            throw new ServiceException( "locator", error );
>        }
>

If you using Merlin you don't need to do all of this. 
You only need to do the following:

    LocationService locator = (LocationService) manager.lookup( "locator" );

All of the checking has already been done before your object is even
instantiated.

>
>
>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?
>

Sorry - I don't understand the above para.  Every lifecycle interface in 
Avalon is optional. In fact is perfectly ok to have an component that 
implements no avalon lifecycle interfaces.  I figure I'm missing 
something - can you expand?

Cheers, Steve.


>
>Eric Pugh
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
>For additional commands, e-mail: dev-help@avalon.apache.org
>
>
>  
>

-- 

Stephen J. McConnell
mailto:mcconnell@apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Mime
View raw message