Date: 2004-01-21T12:12:31
Editor: 130.89.169.128 <>
Wiki: JicarillaWiki
Page: http://lsd.student.utwente.nl/jicarilla/JavaBeansConsideredEvil
no comment
Change Log:
------------------------------------------------------------------------------
@@ -262,8 +262,30 @@
Comment (2003-11-22) by Juergen Hoeller: ''I'd like to note that Spring
not only has autowire but also configurable dependency checks, e.g. check the
population of all non-simple bean properties. This can guarantee a similar
safeness of state as using a constructor - if created in the factory, of
course. Furthermore, as of the upcoming release 1.0 M3, Spring can also invoke
constructors just like Pico now, via autowiring or explicit specification of
constructor arguments.''
Comment (2003-11-24) by Leo Simons: ''Oh, come on, guys! Of course there
is a framework X which has feature Y and will furthermore have feature Z from
framework B in the next release. That is quite irrelevant. The use of
configurable dependency checks does '''not''' guarantee the same kind of
safety. You are moving the problem to the configuration of the dependency
checking, '''and''' introducing a requirement to use a factory (and a rather
elaborate factory at that). It is more complex, more prone to errors, and
requires much more magic to be put in place in order to work.''
- Comment (2003-11-20) by Bo: There are a great many problems with this
article. First, I think your notion of constructors is wrong. The reason
constructors exist isn't to make sure an object is in a 'safe' state but to
make sure it's in a **well-defined** state. To understand the reasoning here,
you have to go back a ways but once upon a time you used to construct objects
that held pointers which literally contained random garbage data. Constructors
were needed to let them zero out these pointers.
+ Comment (2004-01-21) by Bo: ''There are a great many problems with this
article. First, I think your notion of constructors is wrong. The reason
constructors exist isn't to make sure an object is in a 'safe' state but to
make sure it's in a '''well-defined''' state. To understand the reasoning here,
you have to go back a ways but once upon a time you used to construct objects
that held pointers which literally contained random garbage data. Constructors
were needed to let them zero out these pointers.''
-Constructors aren't intended as a way to **configure** objects but as a simple
mechanism to give objects a chance to initialize themselves. This is why the
whole Picocontainer thing is so wrong. You're trying to do both and it's very
doubtful it'll scale to any sort of real complexity. (I shudder to think what
will happen when you try to subclass these complex components that have these
huge constructors. And the simple truth is that a constructor is simply not
expressive enough to completely define a component's dependencies. You couldn't
even configure most EJBs if you just used constructors and interfaces. And
let's not even get into runtime reconfiguration where you have to be moving
databases around without restarting the application...)
+ ''Constructors aren't intended as a way to **configure** objects but as a
simple mechanism to give objects a chance to initialize themselves. This is why
the whole Picocontainer thing is so wrong. You're trying to do both and it's
very doubtful it'll scale to any sort of real complexity. (I shudder to think
what will happen when you try to subclass these complex components that have
these huge constructors. And the simple truth is that a constructor is simply
not expressive enough to completely define a component's dependencies. You
couldn't even configure most EJBs if you just used constructors and interfaces.
And let's not even get into runtime reconfiguration where you have to be moving
databases around without restarting the application...)''
-Second, I think your notion of an 'unsafe state' is backwards. The simple
truth is this: if an object A has a reference to an object B then it got that
reference either 1) by constructing B or 2) by receiving a reference to B. The
question isn't whether B can be in a safe state, it's whether A should know how
to construct B. If A shouldn't know how to constructor B then it needs to be
passed B. This is pretty common sense OO design. In fact, I highly doubt
'unsafe states' are a real problem in java development. I know I've never
needed to write code like 'if (a.isInitialized())' and I've rarely seen such
code long before 'dependency injection' was branded. BTW, if you have public
setters that receive null you should throw an IllegalArgumentException not an
assertion exception. ;)
+ ''Second, I think your notion of an 'unsafe state' is backwards. The simple
truth is this: if an object A has a reference to an object B then it got that
reference either 1) by constructing B or 2) by receiving a reference to B. The
question isn't whether B can be in a safe state, it's whether A should know how
to construct B. If A shouldn't know how to constructor B then it needs to be
passed B. This is pretty common sense OO design. In fact, I highly doubt
'unsafe states' are a real problem in java development. I know I've never
needed to write code like 'if (a.isInitialized())' and I've rarely seen such
code long before 'dependency injection' was branded. BTW, if you have public
setters that receive null you should throw an IllegalArgumentException not an
assertion exception. ;)''
+
+ Comment (2004-01-21) by Leo Simons: ''Thanks for your comments, Bo! I always
enjoy reading strong opinions...you had me thinking for a while :D''
+
+ ''As to "what constructors are for"...java has no pointers, yet it has
constructors. These weren't invented just to make C++ programmers happy. After
all, any instance is always in a "well-defined" state in the sense you refer
to: members are initialized to null, primitives to 0, etc. But why would there
be language support for constructors, and providing arguments in a constructor,
if those mechanisms are not meant to be used?''
+
+ ''As to "constructors are not expressive enough"...that's a very powerful
argument. It seems a lot like using constructors wouldn't, especially not with
complex things like (spit) EJB....well, you can introduce value objects and a
service locator in the constructor, for example. Something like this:''
+
+{{{
+ // Example 9 (fragments)
+ public class MyComponent implements MyContract
+ {
+ public MyComponent( Configuration config, ServiceLocator locator ) { /*
... */ }
+ }
+}}}
+
+ ''...and there's half a dozen other options to explore. It may turn out two
years from now that it was all a bad idea to use them. But I'm going to think
otherwise until someone shows me an example of a big application that sucked
because people were using constructor dependency injection. And I've seen
plenty of big applications that sucked because of overuse of XML, the use of
EJBs, etc etc. Besides that, I've tried some of the options like this, and it
can work, but I've found that in what I consider a well-defined application,
there's really no need for that. If a component does one thing and does it
well, it will have only a few dependencies almost by definition.''
+
+ ''As to "runtime reconfiguration"...okay, there are some proven needs for
that. But if you can't isolate 98% of your application from that, IMHO you're
doing something wrong. Just use some kind of hotswapping technique, or create
new component instances to replace the old ones for new requests, or ...any of
a number of other things.''
+
+ ''As to "I hightly doubt 'unsafe states' are a real problem"...I guess that
depends on how you write your software and whom you work with. If everyone who
works on a project is disciplined in setting up safe state, then unsafe states
are obviously not a problem. With people unit testing things, it becomes less
of a problem everyday. I agree that 'if (a.isInitialized())' is probably not
something you'd come across a lot. But have you never found a bug where a
setXXX was not called or with the wrong arguments, or where a config file was
missing a property? Maybe you work with better programmers than I do :D''
+
+ ''Closing up with the IllegalArgumentException thing...well, I just disagree
(throwing Errors is more efficient and in a properly tested application these
kind of things should never occur), but at least the decision is now isolated
into an Assert class. Throwing IllegalArgumentException instead of
AssertionError in my applications involves changing a single line of code :D''
-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
|