RE: [Embedlets-dev] Re: Class Hierarchy.....
Status: Alpha
Brought to you by:
tkosan
|
From: Christopher S. <cs...@oo...> - 2003-03-08 23:41:12
|
___________
>
> Chris inquires
>
> > On the class hierachy:
> >
> > Is there a reason you have not used interfaces as the starting
> point for the
> > abstract classes? This requires an extra class(interface) but
> it provides a
> > huge amount of flexibility if we need to substitute versions
> (full/lite) or
> > platform specific implementations later.
> >
> > As you know it would be a simple level to add at the top:
> >
> > iComponent
> > ^
> > :__ Component
> > ^
> > |____ Embedlet
>
> This was very deliberate on my part.
>
> It would be simple to add, and could be done later if needed, without any
> impact on derived classes, but doesn't add much flexibilty or
> value at the
> moment (and has a cost). Let me explain my thinking on that....
>
> The Component method implementations only depend on other core
> specifications/interfaces (and no other implementation-dependent
> pieces).
> That is to say, Component uses stuff from LifecycleEnabled,
> EventConsumer and
> Properties, all of which are a mandatory part of the Embedlet
> standard, and
> has nothing in it that is or should ever be platform specific.
>
> The only class that would ever need to implement the ComponentEnabled
> interface (regarding naming conventions, I have used XXXXEnabled for
> interfaces.....LifecycleEnabled, PropertiesEnabled, etc, so would call it
> ComponentEnabled) is the Component abstract class. There should
> be no reason
> to have to implement that interface anywhere else, since managed
> components
> must extend (right now) Embedlet, Service or Adapter (which in
> turn extend
> Component).
>
> Component, as an abstract class, provides the interface definition
> intrinsically (abstract methods) along with default/mandatory/convenience
> method implementations that all components will typically need or have to
> have (eg. setContext() ).
>
> Servlets are designed this way....there is no "iServlet"
> interface....just
> abstract base classes (GenericServlet and HTTPServlet).
Hmmm, my documentation on J2EE says that there is an interface above
HTTPServlet - Servlet!
javax.servlet.http
Class HttpServlet
java.lang.Object
|
+--javax.servlet.GenericServlet
|
+--javax.servlet.http.HttpServlet
All Implemented Interfaces:
java.io.Serializable, Servlet, ServletConfig
If we were following the servlet model it would be:
Component (interface)
^
:___ GenericComponent (abstract)
|
+---- Embedlet (abstract)
|
+---- MyEmbedlet (concrete)
J2EE and most of the formalized container specs that I have seen follow this
design pattern. That is the reason for the (not so) innocent question ;-}.
> There is a fine line with Java best practices on when you use an
> interface
> and when to use abstract base classes. I'm basically following those
> practices here, since the Interface would add nothing in this particular
> scenario.
>
> Adding the interface can also cause method invocations to go through one
> extra redirection during invocation in many JVMs which will impact
> performance on contstrained platforms like the TINI.
>
> > if we need to substitute versions (full/lite)
>
> NO....NO....NO....EMPHATICALLY NO! <grins>
>
I second that NO...
I was in no way suggesting the contract be varied or violated... just that
the abstract implementation at the top level may need to accommodate
platform or optimization specific variations within the contract.
With an interface the contract is enforced but all abstract classes can be
substituted. This is the basis (to extreme lengths perhaps) for EJB
flexibility.
With an abstract class as the root you are stuck forever with the overhead
or perhaps even bugs of that class. This limits vendors (or ourselves) from
coming up with a better mousetrap while still living within the contract...
an impediment to acceptance.
Interfaces are the 'official' enforcers of an API contract not abstract
classes or specifications for that matter.
Abstract classes are actually less formal in their contract enforcement
because one can extend them, write code to use the extension, plug it into
the container and only find out at run time that someone else's Embedlet
does not implement the extension or someone else's container does not call
that method.
With interfaces the extensions are always defined in new interfaces to
maintain backwards compatibility. That way the container has a mechanism to
check e.g.. isAssignableFrom(EmbedletII).
As for overhead, interfaces do not have any because the contract is
validated at compile time and just type checked at run time, there is no
code in an interface. The overhead is in the implied super.xxxx() call chain
of the abstract class hierarchy.
Conclusion:
1. No runtime overhead.
2. More flexibility
3. Tighter contract enforcement
4. Accepted design pattern
All good things and in line with your (and mine) draconian contract
adherence.
> The point of the Embedlet specification is to set some basic (and
> inviolate)
> contracts that ALL components (Embedlets, Services and Adapters
> so far) MUST
> abide by. You either fullfil the requirements of being an Embedlet
> component, or not...there is no "middle ground" where you can implement
> "half" of the Embedlet or Component contract. Allowing for full/lite
> versions of such a contract (basically allowing for subsetting of a
> "contract") is a VERY BAD MOVE since then you blur the definition
> of what an
> "acceptable" Embedlet component is. Doing so then requires a lot of
> conditional logic in both the Embedlet and the Container
> implementation to
> check for what "parts" of a contract are being adhered to...which
> leads to
> ugly, inefficient, replicated and hard to maintain code on both sides.
>
> Per your hierarchy comments, adding a ContainerEnabled interface
> opens a bit
> of a pandoras box in this regard, from a philosophical standpoint, and is
> another reason why I left it out, besides the other reasons listed above.
>
> Philosophically, we need to set the line somewhere in the core
> spec. If you
> look at what Component enforces, it's pretty minimal (same with the next
> level down in the inheritance hierarchy for Embedlets, Services and
> Adapters). That was deliberate so that the contract would not be too
> restrictive, but we do need SOME restrictions/requirements. It's
> the nature
> of container-based systems. Core contracts need to be "all or nothing"
> constructs in a container based system.
>
> Where the flexibility lies in "how" these contracts are
> implemented by the
> container, "under the covers", and that flexibility is still there in the
> current code base. Also, what you do in the Lifecycle start()
> method in a
> component is up to the component to define and is not limited by the spec.
>
> For example, how you manage physical storage of Properties is not
> defined in
> the Embedlet core classes.....it's left up to the Container
> implementation
> (and the Outpost RI code provides just such an implementation). All the
> Embedlet spec part does is enforce how you access/manipulate the
> Properties,
> so that all Embedlets written can do this in exactly the same
> manner and be
> assured that (regardless of underlying implementation) they will
> run on any
> container implementation that satisfies these contracts. In fact, we can
> replace the existing Outpost properties implementation with a
> more optimized
> version (probably a good thing to do down the road, based on my prelim
> benchmakrs) without changing a line of Embedlet code. Same with
> Component....it says that the Component has to implement Lifecycle and
> EventConsumer semantics, but does not limit the component or
> container in how
> they choose to do that implementation.
>
> As soon as you start allowing subsetting (eg. lite versions) of
> contracts
> you break the commonality and cause a huge mess for both application and
> container developers.
>
> So I'm rather adamant that the core spec (org.embedlet package)
> interfaces/abstract classes cannot be subsettable. You either
> implement them
> or you don't. If you don't implement org.embedlet.Component then
> you are NOT
> a component that can be managed by a standard-compliant Embedle
> container.
>
> That being said, we do need to discuss and settle on what those core
> contracts should be (I've tried to take a conservative approach
> in the code
> base, and not put in anything more than necessary, so my gut feel
> is that we
> are more likely to add a few things rather than subtract), and
> hence my RFC
> (request for comments). Note that the spec does allow for a lot of
> flexibility since many services are optional. You don't have to
> implement
> Persistence, Management, Mesh or other optional services.
> However, if you DO
> implement one, then it will have to abide by whatever contract we put in
> place for that "type" of service. To be a "bona fide" Embedlet
> Container,
> you DO have to implement Lifecycle, Event, Logging and Timer services.
>
> There is a lot of opportunity for "subsets" or "lite" versions of actual
> container implementations. You can create an implementation that
> fulfills
> the mandatory part of the Embedlet specification, but that only
> implements
> Lifecycle, Event, Logging (using only the Null logger) and Timer, without
> using threads (for example). That would be a pretty "lite"
> container, but
> what is key is that any Embedlet written to the standard (and
> that did not
> require optional services) would run, unchanged, on this "lite" container.
>
> This is another reason why we don't need the ContainerEnabled
> interface right
> now (and probably will never need one).
>
> In summary:
>
> 1) No subsetting/lite versions of key Embedlets contracts (ie. stuff in
> org.embedlet package) allowed, except where whole components or
> features are
> specifically listed as not mandatory (eg. optional services).
>
> 2) Lite/subsetting of container implementation is a good thing
> and expected
> even, so long as it meets the mandatory contracts laid out by the spec.
>
> Sorry 'bout the long diatribe....but I wanted to get my design
> thinking on
> this point out in the open, since it's a very key point, IMNSHO,
> and needs to
> be understood/agreed to by the whole group.
>
>
> Andrzej Jan Taramina
> Chaeron Corporation: Enterprise System Solutions
> http://www.chaeron.com
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: Etnus, makers of TotalView,
> The debugger
> for complex code. Debugging C/C++ programs can leave you feeling lost and
> disoriented. TotalView can help you find your way. Available on
> major UNIX
> and Linux platforms. Try it free. www.etnus.com
> _______________________________________________
> Embedlets-developer mailing list
> Emb...@li...
> https://lists.sourceforge.net/lists/listinfo/embedlets-developer
>
|