You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Leo Sutic <le...@inspireinfrastructure.com> on 2004/01/23 22:08:58 UTC
[RT] JavaBeans are even more evil than first thought
All,
the discussion of automatically setting fields in the component
based on a component to configuration mapping caused me to think
about the alternatives to reaching into a class and setting
private fields.
For example, we will use a class that has two fields - a minimum
and a maximum range.
public class Radar {
private int minRange;
private int maxRange;
// ...
}
There's one invariant though - the minimum range is always less than
or equal to the maximum range: minRange <= maxRange
Additionally, I'll completely ignore the case of a negative range
value. Focus on the invariant above.
OK, so how are we going to configure this thing?
Attempt 1: Standard Avalon Configuration
public class Radar {
private int minRange;
private int maxRange;
public void configure (Configuration config)
throws ConfigurationException {
minRange = config.getAttributeAsInteger ("min-range");
maxRange = config.getAttributeAsInteger ("max-range");
if (minRange > maxRange) {
throw new ConfigurationException ("min-range >
max-range");
}
}
// ...
}
OK, fine, but not very magic. Not magic enough, in fact, due to the
amount of
boilerplate code.
Attempt 2: Deserialization from XML or similar
public class Radar {
private int minRange;
private int maxRange;
// ...
}
Here we use XStream or similar. So we create an XML file:
<radar>
<minRange>1000</minRange>
<maxRange>2000</maxRange>
</radar>
And we're done. Or? Well, how about:
<radar>
<minRange>2000</minRange>
<maxRange>1000</maxRange>
</radar>
Oops. Broken invariant. No way to detect that unless we do some serious
hackery.
Attempt 3: Use Setters to Validate Values
public class Radar {
private int minRange;
private int maxRange;
public void setMaxRange (int _maxRange) {
if (_maxRange < minRange) {
throw new IllegalArgumentException ("maxRange <
minRange");
}
maxRange = _maxRange;
}
public void setMinRange (int _minRange) {
if (_minRange > maxRange) {
throw new IllegalArgumentException ("minRange >
maxRange");
}
minRange = _minRange;
}
// ...
}
Here the problem is that we can't guarantee in what order the setters
will be
called. Unless they are called in the order setMaxRange, setMinRange,
we're
guaranteed to get an IllegalArgumentException. This is the problem of
constructing
and object with setters - even though they are supposed to provide
validation
of the parameters, due to them being called in sequence, none can
validate the
complete state of the instance before the object is fully constructed.
Anyway, that's why JavaBeans are Evil. Mmmkay?
Attempt 4: Auto-Configuration
public class Radar {
/**
* @@ConfigurableField ("@min-range")
*/
private int minRange;
/**
* @@ConfigurableField ("@max-range")
*/
private int maxRange;
// ...
}
Fails for the same reasons as attempt 2: no validation.
Attempt 5: Auto-Configuration or Deserialization With
Separate configure() Step
public class Radar {
/**
* @@ConfigurableField ("@min-range")
*/
private int minRange;
/**
* @@ConfigurableField ("@max-range")
*/
private int maxRange;
public void configure (Configuration config)
throws ConfigurationException {
if (minRange > maxRange) {
throw new ConfigurationException ("min-range >
max-range");
}
}
// ...
}
Well, *I* think this one is a winner. (Whether it is realized via
XStream
or attributes is not that relevant.)
/LS
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org
RE: [RT] JavaBeans are even more evil than first thought
Posted by Leo Sutic <le...@inspireinfrastructure.com>.
There must be a nit to pick *somewhere*...
> From: news [mailto:news@sea.gmane.org] On Behalf Of Leo Simons
>
> public class Radar {
> private int minRange;
> private int maxRange;
>
> public Radar( int maxRange, int minRange )
> {
> // easy to do the ordering here :D
> setMaxRange( maxRange );
> setMinRange( minRange );
Boilerplate code. Nice when you have two parameters, ugly
when you have twenty.
/LS
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org
Re: [RT] JavaBeans are even more evil than first thought
Posted by Leo Simons <le...@apache.org>.
Leo Sutic wrote:
<snip/>
and another good read! Is this all part of a "let's keep Berin around"
campaign? :D
summary: we want to write just a little bit of code to handle
configuration, and with that, have strong validation of our invariants
and other types of assertions.
You highlight one way it could be done using javadoc tags, reflection
and a configure() method which is essentially a validateInvariants() method.
IMHO: Too Much Magic!
You probably already knew that I was going to say that ;). Maybe we need
to delve into .Net, where we wouldn't be needing a language extension...
Other possible 'solutions' include AOP-based validation (lots of AspectJ
samples around), ugly xml-based interceptor validation (XWork, I think
HiveMind as well), and...constructor dependency injection:
public class Radar {
private int minRange;
private int maxRange;
public Radar( int maxRange, int minRange )
{
// easy to do the ordering here :D
setMaxRange( maxRange );
setMinRange( minRange );
}
// made these protected; you could make them private
protected void setMaxRange (int _maxRange)
{
if (_maxRange < minRange)
throw new IllegalArgumentException(
"maxRange < minRange");
maxRange = _maxRange;
}
protected void setMinRange (int _minRange)
{
if (_minRange > maxRange)
throw new IllegalArgumentException(
"minRange > maxRange");
minRange = _minRange;
}
// ...
}
--
cheers,
- Leo Simons
-----------------------------------------------------------------------
Weblog -- http://leosimons.com/
IoC Component Glue -- http://jicarilla.org/
Articles & Opinions -- http://articles.leosimons.com/
-----------------------------------------------------------------------
"We started off trying to set up a small anarchist community, but
people wouldn't obey the rules."
-- Alan Bennett
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org
Re: [RT] JavaBeans are even more evil than first thought
Posted by Niclas Hedhman <ni...@hedhman.org>.
On Friday 23 January 2004 13:08, Leo Sutic wrote:
I have also spent some thinking of the "boilerplate" configuration you are so
concerned about.
public class Radar
{
/** @configurable-property name="min-range" */
private int minRange;
/** @configurable-property name="max-range" */
private int maxRange;
public void configure (Configuration config)
throws ConfigurationException
{
ConfigurationUtility cu = new ConfigurationUtility();
cu.poplute( this, config );
if (minRange > maxRange) {
throw new ConfigurationException ("min-range >
"max-range");
}
}
}
And the ConfigurationUtility class, would tie the XML elements to the private
properties.
The ConfigUtility could even invoke more than one strategy (doc-tags,
reflection, setters) accordingly.
It also removes it from being a container concern and has nothing to do with
Framework.
Wouldn't something like this work fairly nicely?
Niclas
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org