Bernd Fondermann wrote:
mmhh. I am religiously against religion in programming, too. ;-)
Earlier you proposed to get rid of abstract discussions like POJO vs.
Avalon. At least, please don't put me in a corner. This is only for
discussion.
Sorry Bernd, I didn't want to put you in a corner :-)
On the interface topic:
Some James code forensic:
Disposable declares one method with no arguments, dispose().
There is no single variable declared of type Disposable.
Instead, all current uses of Disposable are
if (obj instanceof Disposable) (Disposable) obj).dispose();
and could very well be replaced by ContainerUtil.dispose();
Most of James should use ContainerUtil instead of the instanceof. I
change the "instanceof" method with the ContainerUtil call each time I
work on a james object :-).
So, Disposable is a marker interface.
Exactly.
AFAIK, there is no enforcement of calling dispose() for Disposable
objects which are not handled by Avalon itself through a central
lifecycle handler or something alike.
Who knows if Disposable instances really are disposed? Or if the class I
am calling ContainerUtil.dispose() on is really disposable?
Exactly we can't be sure this will happen. It is simply a contract.
Also in SDI IoC you can't be sure that your dependencies will be followed.
The lifecycle methods, by their nature, are only a contract and it is
left to the container to call them.
So all the interface says is: This class is ready/expecting to be
disposed. (Which is ok.)
But if you read: "This class will get disposed" you are on the wrong
track. The class contract would promise you something the application
can not hold.
Ok, but this is really a common issue in ANY container. I still don't
get the point.
If you don't expect the container and your code to do what it is
supposed to do then you could even expect it could even not start your
application :-)
Pls take a look at the instance variable
Mail mail
in SMTPHandler.
interface Mail extends Serializable, Cloneable (not Disposable)
SMTPHandler receives a Mail instance and at some point calls dispose().
But if it does not get a MailImpl (implementing Disposable) but some
other implementation (not implementing Disposable)?
Nothing happens. (Which is: bad things happen ;-) )
@SMTPHandler:417
if (mail instanceof Disposable) {
((Disposable) mail).dispose();
}
So if the Mail is not a MailImpl and does not implement disposable won't
be disposed. And this is GOOD thing.
I don't see where the bad things happen: the mail will be garbage collected.
It seems to me an acceptable contract: you send me disposable stuff I
dispose it, otherwise not.
Furthermore, this kind of lifecycle on "non top level objects" cannot be
delegated to the container. So James have to manually manage the
lifecycle of that objects (mails for example).
Can you explain me how it can work better with no "Disposable" interface?
[note to me: remember to change it to ContainerUtil.dispose(mail)]
The use of lifecycle marker interfaces tries to improve the 'overall
contract' of a class in a specific container environment on one hand but
is hindering class reuse on the other hand.
I don't see how an interface limit an object in any way.
Can you tell me something you can do on the object not implementing
Disposable that you cannot do on the object implementing Disposable?
As you said, Disposable is a marker interface, you can think at it as
something similar to a marker annotation.
On topic reflection:
I really don't see why using reflection is a bad thing compared to the
current cast-to-call invocation of Disposable. They seem more or less
equivalent.
1) reflections reduce the code browsability.
2) if I use a third party object that implement a dispose method called
by itself in its own lifecycle and not intended to be called by me (or
the avalon container) I would do the wrong thing.
3) you can use reflections also with the Disposable interface there, but
you can't do the opposite.
James currently already uses dynamic invocation, so this is no big deal,
isn't it? (Or do you think that should be removed eventually?)
The fact that we already have possible bottlenecks is not a good reason
to introduce new ones :-)
Can you list the advantages of removing the Disposable interface?
Here is the only one I see:
1) reduce the size of James by 162bytes (the size of the
Disposable.class) + something like 40 bytes for each implementing
object. Maybe 2Kb in total.
Any other pro?
for example, a container could be configured to call the dispose()
method declarative where Avalon uses Disposable casts.
pseudocode: <component class="X" onDestroy="dispose" />
(while dispose calls from within James still use the
ContainerUtils-approach.)
We can do this without removing the Disposable interface.
Probably, but it will always get in your way.
Again, these are just thoughts to comparing the current approach to
things Spring framework or XBean are doing. Everyone with its strengths
and weaknesses.
I never read that Spring and XBean suggest to remove interfaces from
objects.
In fact I always thought that Spring/XBean and "current approach to
things" was programming against interfaces and "leave the reflection job
to the container".
And, I'd still prefer to put a release out _before_ starting any
branches for container replacement.
Bernd
I agree.
Stefano
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]