You guys also need to keep in mind that doing dynamic loading of implementations classes may need to be implemented differently based on the container that the app is running in. A good example is OSGi. The way factories are currently implemented would probably not work there. So it's best to avoid getting into the factory business to begin with.
On Fri, Aug 2, 2013 at 10:55 AM, Rob Godfrey <rob.j.godf...@gmail.com> wrote: > Given the Proton class doesn't require the user to know which > implementation they are using (but allows them to explicitly ask for a > particular implementation type if they so desire) I'm a little confused how > adding the requirement for the user to instantiate an implementation > specific class actually helps the user. Am I missing something? There > really is no need for a user to know about factories, etc... > > -- Rob > > > On 2 August 2013 15:13, Rafael Schloming <r...@alum.mit.edu> wrote: > >> On Fri, Aug 2, 2013 at 4:44 AM, Phil Harvey <p...@philharveyonline.com >> >wrote: >> >> > I agree that o.a.q.p.Proton is, overall, an improvement. I was partly >> > responsible for creating the ProtonFactoryLoader and XXXFactory classes, >> > and acknowledge that they make life too hard for the user. >> > >> > This was a result of trying to meet the following design goals: >> > 1. User code should not need to have a compile-time dependency on any >> > proton-c/j/jni classes. Given our current separation of the proton-api >> > from the proton-impl/proton-jni modules, it means user code should only >> > depend on proton-api at compile-time. >> > 2. Classes from the various "top level packages", such as engine, >> messenger >> > etc, should be kept separate unless they really need to be together. >> > >> > I still believe in goal 1 (though this will be discussed at greater >> length >> > on the related thread ), but am relaxed about item 2. >> > >> >> Thanks for describing the goals, it's helpful to have them written down. I >> personally don't feel that the Proton class is violating (2) in an >> important way so long as engine and messenger remain otherwise unentwined. >> >> I generally agree with (1) also, however I think it could use some further >> refinement. At the root of (1) is the desire to make it clear and obvious >> to developers if/when they are depending on the characteristics of a given >> implementation rather than on a more abstracted interface. Probably the >> most common example of this sort of thing within Java would be typical >> collections usage of interface/impl splits, e.g.: >> >> List foo = new ArrayList(); >> ArrayList bar = new ArrayList(); >> LinkedList baz = new LinkedList(); >> >> The suggested pattern for the Proton class would be following this pattern >> exactly: >> >> Proton p = new ProtonJ(); >> ProtonJ pj = new ProtonJ(); >> ProtonC pc = new ProtonC(); >> >> Now this pattern of course doesn't really speak to classpaths at all. The >> classpath issue is really entirely orthogonal to the interface/impl >> distinction. Right now we have separate classpaths, but a muddled >> interface/impl distinction since the impl jar adds new interfaces into >> packages belonging to the API jar, and the API jar has stuff in it that is >> really part of a specific impl. Likewise, you can have a clear >> interface/impl distinctions within a single jar as is the case with java >> collections. >> >> I'd argue that the classpath thing is really a distinct goal/requirement >> and is really more about a discovery mechanism for independent or third >> party implementations. I don't personally feel that this is a necessary >> requirement for us at this point, but I'm fairly relaxed if other people >> would like to support it. >> >> Given the above refinement of (1) into (1a) interface/impl split and (1b) >> independently implementable API, I would find it a bit odd to put the >> ProtonJ/ProtonC classes into the API package since that would introduce a >> dependency from the API package back to those impls (even if its only a >> runtime dependency) and would effectively give those impls an elevated >> position which in some sense is fine, but also seems contrary to the >> independently implementable notion in the first place. It seems like what >> you'd want in the API package is purely a generic discovery mechanism that >> would work for any implementation. >> >> As I said above, I don't feel like such a discovery mechanism is really a >> requirement for us right now. I think actually having a complicated >> discovery/factory pattern is in some ways detrimental as it creates a >> barrier to entry for all users when most don't care about the flexibility >> it offers (at least right now) and if they do care about that flexibility >> it is easy enough for them to build their own. In fact modulo exception >> handling it is really just one extra line of code: >> >> Class impl = Class.forName(System.getProperty("blah")); >> Proton p = (Proton) impl.newInstance(); >> >> So I'd personally say go for the simple interface/impl split pattern that >> everyone knows and is used to and don't worry about a generic discovery >> mechanism until we actually have enough implementations for it to be >> warranted. >> >> --Rafael >> -- Hiram Chirino Engineering | Red Hat, Inc. hchir...@redhat.com | fusesource.com | redhat.com skype: hiramchirino | twitter: @hiramchirino blog: Hiram Chirino's Bit Mojo