You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Anton Tagunov <at...@list.ru> on 2004/02/10 18:39:23 UTC

Configuration mutations. 4 more options -- plz can the vote wait another couple of days?

Hi, gang!

Really hate to delay the final vote on this
not-so-vital issue. However it is only today
that my ideas got crystallized on the subject.

I by no means want to confront LSU. It's only
my perfectionism, want every idea to be polished
as ivory tower fragment :-)

Will you have a look at 4 alternative architectures
for mutationg configuration?

Can we complete the vote then -- I feel we will now
really have 5 options to choose from: the one from LSU
and 4 these I have put together from all I've learned
on Java development and software design patterns:

/**
 * @author Anton Tagunov
 */
interface Configuration{}

/**
 * This interface abstract the API for changing
 * a {@link #Configuration}.
 */
interface ConfigurationMutator
{
	void setValue( String value );
	void setValue( int value );
	void setValue( long value );
	void setValue( boolean value );
	void setValue( float value );
	void setValue( double value );
	
	void setAttribute( String name, String value );
	
	void setName( String name );
	
	/**
	 * It is provisioned that many configuration
	 * nodes will share the same <code>base</code>,
	 * for instance fileName. However concatenating
	 * <code>base</code> with <code>lineNo</code>
	 * and <code>posNo</code> is allocating a new
	 * String and is worth doing so only when this
	 * information is about to be communicated to
	 * user, for instance, if an exception has
	 * occured.
	 * 
	 * @param base base name of configuration location,
	 *     file name, url, jdbc uri, <code>null</code>
	 *     if N/A
	 * @param lineNo <code>-1</code> if N/A
	 * @param posNo <code>-1</code> if N/A
	 */
	void setLocation( String base, int lineNo, int posNo );
	
	void setNamespace( String namespace );
	void setPrefix( String prefix );
	
	/**
	 * Create a child and insert it to position
	 * <code>pos</code>
	 */
	ConfigurationMutator createChild( int pos );
	
	void removeChild( int pos );
	
	/**
	 * Each ConfigurationMutator has got an
	 * instance of Configuration interface implementation
	 * that it is closely tied with. This configuration
	 * gives access to the data that ConfigurationMutator
	 * changes. Their <code>getChildCount()</code>
	 * methods always return the same value.
	 * And the tree formed by getChild() invocations
	 * exactly parallel each other.
	 * 
	 * <p>
	 * The ConfigurationMutator and Configuration
	 * interfaces are implemented with different
	 * objects so that components which have been
	 * given a Configuration instance wouldn't be
	 * able to cast it to <code>MutableConfiguration</code>
	 * 
	 * @return our peer {@link #Configuration} instance.
	 */
	Configuration getConfiguration();

	int getChildCount();

	ConfigurationMutator getChild( int i );
}

/**
 * ConfigurationMutator (see above) 
 * has got a slight drawback:
 * it doubles the number of objects that need to
 * be craeted: for each node we have a Configuration
 * and a ConfigurationMutator.
 * 
 * This class is an attempt to use "Builder" pattern
 * to overcome this drawback. There is only one
 * Builder per Configuration tree.
 * 
 * A builder instance may be used only to modify the
 * Configuration instances obtained from its own
 * {@link #getRoot} and {@link #createChild} methods.
 * 
 * This rule may be enforced for instance by
 * putting a reference to the builder into
 * each of the Configuration instances it
 * produces. Or an implementation my choose
 * not to enforce this limitation.
 * 
 * The clients should treat this limitation as being
 * enforced and never to violate it.
 * 
 * Alternative name: ModifiableConfigurationTree
 * 
 * @author Anton Tagunov
 */
interface ConfigurationBuilder
{
	void setValue( Configuration node, String value );
	void setValue( Configuration node, int value );
	void setValue( Configuration node, long value );
	void setValue( Configuration node, boolean value );
	void setValue( Configuration node, float value );
	void setValue( Configuration node, double value );
	
	void setAttribute( Configuration node, String name, String value );
	
	void setName( Configuration node, String name );
	void setLocation( Configuration node, String location );
	void setNamespace( Configuration node, String namespace );
	void setPrefix( Configuration node, String prefix );
	
	Configuration getRoot();
	
	Configuration createChild( Configuration node, int pos );
	
	void removeChild( Configuration node, int pos );
}

/**
 * Here's a third attempt at improving the mutable
 * configuration interface. DefaultConfiguration
 * interface is over-crowded. It is enough to
 * implement only basic functionality, utility
 * methods can do the rest w/o knowning a concrete
 * class.
 * 
 * This is an abridged version of MutableConfiguration
 * interface.
 * 
 * There is also a crucial difference in ideology
 * between ConfigurationMutator/ConfigurationBuilder
 * and MutableConfiguration[Abridged]:
 * 
 * the former (Builder/Mutator) enforce a homogenous
 * configuration hierarchy, it consists only of
 * instances of same class. And IMO this makes sense,
 * Configuration is mostly about storing information
 * in a tree. So it makes sense to provide a single
 * implementatino of the whole graph at once.
 * 
 * (The only subtlety is the getLocation() method, though,
 * you see the trick I've tried to use to overcome this
 * difficulty in Builder/Mutator.)
 * 
 * the present class allowes for heterogenous configuration
 * trees, clients now depend on some ConfigurationFactory
 * class to provide 'em configurations or on concrete
 * implementations
 * 
 * Also note that all of Builder/Mutator and
 * HomogenousMutableConfiguration (bellow) indirectly
 * enforce the rule that a Configuration node may
 * have noly one parent. This interface does not
 * (although implementation may do it).
 */
interface MutableConfigurationAbridged extends Configuration
{
	void setValue( String value );
	void setValue( int value );
	void setValue( long value );
	void setValue( boolean value );
	void setValue( float value );
	void setValue( double value );
	
	void setAttribute( String name, String value );
	
	void setName( String name );
	
	void setLocation( String base, int lineNo, int posNo );
	
	void setNamespace( String namespace );
	void setPrefix( String prefix );
	
	void addChild( int pos, MutableConfigurationAbridged child );
	void removeChild( int pos );
	
	boolean isReadOnly();
	void makeHierarchyReadOnly();
}

/**
 * Same as MutableConfigurationAbridged, but enforces homogeneity.
 * @author Anton Tagunov
 */
interface HomogenousMutableConfiguration extends Configuration
{
	void setValue( String value );
	void setValue( int value );
	void setValue( long value );
	void setValue( boolean value );
	void setValue( float value );
	void setValue( double value );
	
	void setAttribute( String name, String value );
	
	void setName( String name );
	
	void setLocation( String base, int lineNo, int posNo );
	
	void setNamespace( String namespace );
	void setPrefix( String prefix );
	
	HomogenousMutableConfiguration createChild( int pos );
	void removeChild( int pos );
	
	boolean isReadOnly();
	void makeHierarchyReadOnly();
}

Thank you for your patience with me,
Anton




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