When I asked the original question I had been assuming that the contrib modules were intended to be using the proton-api interfaces, but had to resort to concrete types for tactical reasons pending a more complete API.
If that assumption were true, then using factory interfaces rather than constructors would clearly be necessary. But if this assumption is false then I personally have no problem with concrete classes being instantiated and used directly. However, at the risk of putting words into Rob's mouth, I guess he may be viewing the use of concrete classes across module boundaries to be A Bad Thing that tends to lead to leaky abstractions. Whether we apply that rule on Proton is an interesting question, and is one of those areas where I care more about us being consistent than about being "right". Phil On 24 January 2013 19:03, Rafael Schloming <r...@alum.mit.edu> wrote: > On Thu, Jan 24, 2013 at 5:06 AM, Rob Godfrey <rob.j.godf...@gmail.com > >wrote: > > > On 23 January 2013 17:36, Phil Harvey <p...@philharveyonline.com> wrote: > > > > > > As part of the Proton JNI work, I would like to remove all calls to > > > proton-j implementation constructors from "client code". I intend that > > > factories will be used instead [1], thereby abstracting away whether > the > > > implementation is pure Java or proton-c-via-JNI. > > > > > > I'd like to check that folks are happy with me making this change, and > to > > > mention a couple of problems I've had. > > > > > > In this context, "client code" is anything outside the current > > > sub-component, where our sub-components are Engine, Codec, Driver, > > Message > > > and Messenger, plus each of the contrib modules, and of course third > > party > > > code. > > > > > > To enforce this abstraction, I am planning to make the constructors of > > the > > > affected classes package-private where possible. I believe that, > > although > > > third party projects might already be calling these constructors, it is > > > acceptable for us to change its public API in this manner while Proton > is > > > such a young project. > > > > > > > +1 to all of the above > > > > > > > > Please shout if you disagree with any of the above. > > > > > > Now, onto my problem. I started off with the > > org.apache.qpid.proton.engine. > > > impl package, and found that o.a.q.p.hawtdispatch.impl.AmqpTransport > > calls > > > various methods on ConnectionImpl and TransportImpl, so simply using a > > > Connection and Transport will not work. I don't know what to do about > > > this, and would welcome people's opinions. > > > > > > > So, the simplest change would be to change the factories to use > > covariant return types > > > > e.g. EngingFactoryImpl becomes: > > > > @Override > > public ConnectionImpl createConnection() > > { > > return new ConnectionImpl(); > > } > > > > @Override > > public TransportImpl createTransport() > > { > > return new TransportImpl(); > > } > > > > > > ... etc > > > > Code that requires the extended functionality offered by the pure Java > > implementation can thus instantiate the desired Factory directly. > > > > What's the point of going through the factory in this scenario rather than > directly instantiating the classes as Hiram suggests? Is there some class > of thing the factory would/could do that the constructor can't/shouldn't? > > A second refinement might be to actually separate out the interface > > and implementation within the pure Java implementation so that we have > > a well defined "extended" Java API. This interface could then be the > > return type of the factory. > > > > Maybe I'm misunderstanding, but what's the point of using an interface here > if you're still locked into the pure Java impl? Are you expecting to swap > out that impl under some circumstances? > > --Rafael >