Marshall Schor wrote:
Jörn Kottmann wrote:
Here's another (probably weak) use case for returning <T extends
AbstractCas> kinds of things:  If you have part of the code which
collects views and some of these views use one form of the AbstractCas
(e.g. CASImpl) and others use the JCas form, it would be nice to be able
to put these two uses into a collection (of AbstractCas) - which is the
kind of thing AbstractCas was trying to do, I believe.
I never really understood the reason why AbstractCas exists,
it only has a release method, but CAS and JCas have many methods in
common. Why are they not declared in AbstractCas ?

The way its now AbstractCas is nearly useless expect
for cas pooling or so.

What was the reason to not move up the common methods
when AbstractCas was introduced ?

Good question :-)  -- I wasn't involved with the design here, but I can
think of 2 reasons (there may be others).  (1) API stability - not
wanting to change existing APIs.  I haven't studied API evolution as
much as I might, but I think this kind of change would cause a binary
incompatibility.
We can move up these methods. And yes its not binary compatible,
because it breaks all implementations of AbstractCas, but in our
case we could do it because the interface is not intended to be
implemented by clients. Anyway we should double check this.

(2) Some methods are the same except that in the CAS they return things
of type CAS, and in the JCas they return things of type JCas.  So some
kind of overloading is possible if the arguments are CAS vs JCas, but is
not possible if the returned types are CAS vs JCas.  In this case, the
solution might be to return things of AbstractCas type.
Lets take the case of getViewIterator:

AbstractCas:

<T extends AbstractCas> Iterator<T> getViewIterator() throws CASException

CAS:

<T extends CAS> Iterator<T> getViewIterator()


JCas:

<T extends JCas> Iterator<T> getViewIterator() throws CASException


I am not sure about the exception, but looks fine to me.

Jörn

Reply via email to