Thanks all for your feedback. But in this case, I don't want to revert to hacks to bypass dependency declaration impact. And going for artificial composition would be a hack, how strange it may seem.
E.g. the adapter implementations ARE adapters. They don't HAVE adapters (i.e. the classical IS-A vs HAS-A thing does not help me here). Composition is ok when you have things to compose. Also, using interfaces as refered types is the default approach in our stuff. But at some point the varying implementations must be just .... implemented... And then it's nice to be able to define common stuff in a base-class, i.o. needing to copy it around every time or artificially forcing in a couple of design patterns. Even when building modular solutions... I need to reflect some more on this to find the fundamental issue, but I have the impression that there is a kind of mismatch between "encapsulation of dependencies" versus "needs related to (ease of?) compilation". Especially in the first case I described, it would be nice if the choice to implement a given ClassB via inheritance or via copy/paste, could be encapsulated in the bundle B's implementation. Without needing to expose this as a forced dependency on "client" bundles... Neil, as you explain indeed, for the second situation I described before, replicating dependencies could be considered a bit more natural than in the first situation. Although even in the second case I would assume that as long as class A does not contain any reference to any C-types, there is no need to replicate this dependency in bundle A. You also don't need to add any C-related import statements in the Java source code of A, after all? (but I must confess : I don't know the internals of class loading or compiling; I'm just looking at it from a design and development perspective) cheers and thanks again for your time and thoughts! erwin On Tue, Jan 29, 2013 at 2:30 PM, Toni Menzel <[email protected]> wrote: > Thanks Neil, actually with "composition" i included the use of OSGi > Services. Its the old story that is true not just in OSGi: avoid > inheritance if you seek true modularity. > > *Toni Menzel | Founder Rebaze GmbH* > [email protected] | +49 171 65 202 84 > http:// <https://mail.google.com/mail/u/0/goog_1770677242>www.rebaze.com > | twitter @rebazeio <https://twitter.com/rebazeio> | LinkedIn > Profile<http://www.linkedin.com/company/2553599> > > *Rebaze Pilot: *The free one day onsite consulting opportunity. We will > capture your potential. > *Rebaze Pass: *A unique subscription service for key technologies in your > project. > *Rebaze Onsite: *Our way to improving your development team on site. > > > On Tue, Jan 29, 2013 at 2:21 PM, Neil Bartlett <[email protected]>wrote: > >> This seems an entirely reasonable requirement. It doesn't come from PDE >> as such but from the Java compiler. A directly inherits from B. The public >> interface of B uses types from C (as you said, C is either a method >> argument or return type). Therefore the Java compiler needs visibility of >> both B and C when it compiles A. >> >> A direct runtime dependency from A to C *may* not be necessary if A >> doesn't use the C types at all. Unfortunately PDE does not allow for >> separation of compile-time versus runtime dependencies, so you still have >> to add the Import-Package in order to create the compile-time visibility. >> >> This could possibly be avoided if you make more use of Java Interfaces >> and OSGi services. For example, make sure that all implementation bundles >> (i.e. those containing executable code) depend only on the interfaces, and >> not on each other. >> >> Neil >> >> >> On Tue, Jan 29, 2013 at 12:27 PM, erwin dl <[email protected]> wrote: >> >>> Hi Toni, >>> >>> Thanks for your quick advice. >>> And indeed that's what I do : >>> >>> - I am using package imports, not bundle dependencies >>> - Composition is the default approach, but just doesn't cut it in >>> all situations >>> - In general I do try to follow all kinds of rules for "good modular >>> and OO design" >>> - But in some concrete design situations I am trying to match it to >>> minimal module/bundle dependencies, which is also a rule I have >>> - And the sketched situation bothers me in that respect >>> >>> As an extra, I also encounter following situation, as a slight variation >>> on the previously described one : >>> >>> - ClassA now inherits from ClassB (again in 2 separate bundles). In >>> fact there are many different subclass implementations of ClassB, all in >>> different implementation bundles. >>> - ClassB depends on a ClassC in a bundle C, in one of its method >>> signatures (i.e. ClassC is used as an argument or return type) >>> - I get an error in the PDE compilation : "The type ClassC cannot be >>> resolved. It is indirectly referenced from required .class files" >>> - As a consequence it seems I also need to add an explicit >>> dependency (done via import package) of all implementation bundles (like >>> bundle A) to the bundle C. >>> Whereas I would hope/expect that this dependency is already clearly >>> defined in bundle B... >>> >>> With some more concrete explanation : >>> >>> - We're building a modular processing engine, that can be extended >>> with specific "backend adapters" to perform data collection to/from other >>> systems >>> - Most complexity of the adapter is implemented once and reusable, >>> in an adapter base class e.g. "BaseBackendAdapter". >>> - The adapters are used by a common "BackendService" implementation >>> that has a reference to its adapter (i.e. composition). The reference is >>> typed to the "BaseBackendAdapter". >>> BackendService and BaseBackendAdapter are provided in a common >>> "base" bundle. >>> - Each concrete adapter bundle registers a BackendService instance, >>> with its dedicated concrete adapter, as an "OSGi" service etc. >>> Implementation code in the concrete adapter bundles depends really >>> on actual communication APIs etc. >>> - So I would prefer to have just 2 main dependencies : on the base >>> bundle and on the concrete communication API. >>> - Problem is now, that I need to replicate some dependencies of the >>> "base" bundle in each concrete adapter bundle, which I don't like... >>> >>> >>> cheers >>> >>> erwin >>> >>> >>> >>> On Tue, Jan 29, 2013 at 1:01 PM, Toni Menzel <[email protected]>wrote: >>> >>>> Quick answer to parts of your question: >>>> >>>> - Prefer composition over inheritance. Just don't build on >>>> inheritance and your developer life, not just the OSGi one, will be >>>> better >>>> ;) >>>> - Avoid Bundle dependencies. If you encounter a situation where you >>>> have the abstract class and the final one in same package you should >>>> carry >>>> it around in one bundle. Otherwise just make the abstract one explicit >>>> by >>>> giving it a separate package. (avoid split package) >>>> >>>> You learn this quickly by avoiding PDE. >>>> Toni >>>> >>>> >>>> *Toni Menzel | Founder Rebaze GmbH* >>>> [email protected] | +49 171 65 202 84 >>>> http:// <https://mail.google.com/mail/u/0/goog_1770677242> >>>> www.rebaze.com | twitter @rebazeio <https://twitter.com/rebazeio> | >>>> LinkedIn >>>> Profile <http://www.linkedin.com/company/2553599> >>>> >>>> *Rebaze Pilot: *The free one day onsite consulting opportunity. We >>>> will capture your potential. >>>> *Rebaze Pass: *A unique subscription service for key technologies: >>>> OSGi, Maven, Chef, Jenkins. >>>> *Rebaze Onsite: *Our way to improving your development team on site. >>>> >>>> >>>> On Tue, Jan 29, 2013 at 12:41 PM, erwin dl <[email protected]> wrote: >>>> >>>>> I often encounter situations where a certain class ClassA in a bundle >>>>> A depends on a class ClassB in a bundle B, and where ClassB is a subclass >>>>> of ClassC in a bundle C. >>>>> >>>>> So it is logical that bundle B has a dependency on bundle C. >>>>> >>>>> But to get the things compiled and working, I am forced in such a >>>>> situation to also add an explicit dependency of bundle A on bundle C. >>>>> Even when not directly referring to the base-class in my ClassA... >>>>> >>>>> At least this is true in eclipse's PDE. >>>>> But in internal discussions here, it seems to be perceived as an >>>>> inevitable fact, independent of eclipse or equinox implementation >>>>> choices... >>>>> >>>>> I would prefer that the implementation decision of ClassB, to inherit >>>>> part of its stuff from ClassC, i.o. implementing it directly itself, would >>>>> be hidden for ClassA and bundle A. >>>>> >>>>> I.e. it is not a situation where a kind of API is provided in bundle >>>>> C, and where bundle A would better use the API, and where bundle B >>>>> provides >>>>> implementations as services etc. >>>>> It's a simple class-hierarchy set-up that exposes implementation >>>>> decisions and forces dependents to add a-priori "unnecessary" extra >>>>> dependencies... >>>>> >>>>> If someone has advice or ideas on this, I would be very interested to >>>>> hear/learn from them! >>>>> >>>>> Many thanks, >>>>> erwin >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> OSGi Developer Mail List >>>>> [email protected] >>>>> https://mail.osgi.org/mailman/listinfo/osgi-dev >>>>> >>>> >>>> >>>> _______________________________________________ >>>> OSGi Developer Mail List >>>> [email protected] >>>> https://mail.osgi.org/mailman/listinfo/osgi-dev >>>> >>> >>> >>> _______________________________________________ >>> OSGi Developer Mail List >>> [email protected] >>> https://mail.osgi.org/mailman/listinfo/osgi-dev >>> >> >> >> _______________________________________________ >> OSGi Developer Mail List >> [email protected] >> https://mail.osgi.org/mailman/listinfo/osgi-dev >> > > > _______________________________________________ > OSGi Developer Mail List > [email protected] > https://mail.osgi.org/mailman/listinfo/osgi-dev >
_______________________________________________ OSGi Developer Mail List [email protected] https://mail.osgi.org/mailman/listinfo/osgi-dev
