Benefits

Seperating Concerns

Every developer that has written a complex component based application has had to deal with container-side programming. Given normal commercial pressures, it too easy to write code into your application that has assumptions built into it concerning the requirements of the target components.

Consider the following code fragment:


    // and example of a bad practice of introducing 
    // component deployment strategy and dependencies
    // into your application logic 

    DefaultMonitor monitor = new DefaultMonitor();
    
    DefaultContext context = new DefaultContext();
    context.put( "classloader", m_classloader );
    context.makeReadOnly();

    monitor.enableLogging( m_logger );
    monitor.contextualize( context );
    monitor.initialize();

The above container-side code is making a lot of assumptions about the component it is deploying. Firstly, it knows that the component is log enabled, contextualizable, and initializable. This is problematic because it means that the container-side code is dependent on the component implementation. If the component were to be changed so that it supported the configurable semantics, there container-side code needs to be updated as well. This is dangerous because it is easy for container-side to get out-of-sync with the component implementation - for example, the container side code to some extent is dependent on a component properly checking if it has been configured or not. A deeper and more important issue concerns component assembly - if a component is refactored to use other components, then the container-side code become much more complex and much more closely tied to the set of components that make up the assembly.

The solution to the above is a framework that automates the process of component deployment. The end result is that container side code becomes independent of the component deployment strategy and component dependencies.

Consider the following code fragment:


   // add an implementation component to the engine

   engine.register( "org.apache.avalon.playground.BasicComponent" );

   // get an appliance handling the versioned service we want

   Appliance appliance = m_engine.resolve( 
     new DependencyDescriptor( 
       "demo", 
       "org.apache.avalon.playground.BasicService", 
       Version.getVersion( "1.1" ) ) 
   );

   // get the fully prepared component

   Object object = appliance.access( dependency );

The above code demonstrates the elimination of knowledge about the component deployment strategy. All aspect concerning the component logging, configuration, parameterization, contexulization, dependency composition, initialization, startup, shutdown, and disposal are managed by the engine.