On Tue, Jan 29, 2013 at 4:28 PM, erwin dl <[email protected]> wrote:
> 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? > Yes, as I said, the direct runtime dependency *may* not be needed. If you used bnd/Bndtools then the Import-Package would be added if-and-only-if you directly used C from within A. However you would still need C on the compile-time classpath for project A, because the Java compiler needs it. You cannot get around that fact if you structure your code this way. > > (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 >
_______________________________________________ OSGi Developer Mail List [email protected] https://mail.osgi.org/mailman/listinfo/osgi-dev
