You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@lenya.apache.org by Andreas Hartmann <an...@apache.org> on 2006/04/06 17:40:48 UTC

[1.4] Separate API and Implementation?

Hi Lenya devs,

currently, it's not clear which classes+interfaces form
the Lenya API (i.e., have to stay backwards compatible
and therefore may be used by client code).

Examples are AbstractUsecase and DocumentUsecase:
Can you extend these classes without the danger of
incompatible changes in future 1.4.x versions?


I like the approach taken by Avalon/Excalibur:

- framework/api/src/java
- framework/api/src/test
- framework/impl/src/java
- framework/impl/src/test

For example: AbstractLogEnabled is part of the API,
AbstractConfiguration is not. A disadvantage of this
approach is that you can't tell whether a class is
part of the API without knowing where it is located
in the source tree. Maybe we can solve this using
package names which contain "impl":

o.a.lenya.cms.usecase.*
o.a.lenya.cms.usecase.impl.*


Modules are another story, but maybe the same concept
can be applied there.


WDYT?

-- Andreas


-- 
Andreas Hartmann
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
andreas.hartmann@wyona.com                     andreas@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


Re: [1.4] Separate API and Implementation?

Posted by Andreas Hartmann <an...@apache.org>.
Andreas Hartmann schrieb:

[...]

> Another very nice solution would be to split up the
> core into modules or Cocoon blocks:
> 
> - core-api
> - core-impl
> 
> Modules would depend only on the core-api module/block
> (and other modules), which would ensure that they don't
> reference internal classes or interfaces.

Hmmm - I just noticed that this doesn't make sense.
The separation between API and implementation should be
orthogonal to modularization, for instance to allow that
modules provide their own API.

IIUC Cocoon's "real blocks" should even support polymorphism
at block level, which means that multiple blocks can implement
a specific interface.

-- Andreas


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


Re: [1.4] Separate API and Implementation?

Posted by Andreas Hartmann <an...@apache.org>.
Andreas Hartmann schrieb:
> Hi Lenya devs,
> 
> currently, it's not clear which classes+interfaces form
> the Lenya API (i.e., have to stay backwards compatible
> and therefore may be used by client code).
> 
> Examples are AbstractUsecase and DocumentUsecase:
> Can you extend these classes without the danger of
> incompatible changes in future 1.4.x versions?
> 
> 
> I like the approach taken by Avalon/Excalibur:
> 
> - framework/api/src/java
> - framework/api/src/test
> - framework/impl/src/java
> - framework/impl/src/test


Another very nice solution would be to split up the
core into modules or Cocoon blocks:

- core-api
- core-impl

Modules would depend only on the core-api module/block
(and other modules), which would ensure that they don't
reference internal classes or interfaces.

-- Andreas


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


Re: [1.4] Separate API and Implementation?

Posted by Andreas Hartmann <an...@apache.org>.
Andreas Hartmann wrote:
> Thorsten Scherler wrote:
>> El vie, 07-04-2006 a las 13:30 +0200, Andreas Hartmann escribió:
>>> Thorsten Scherler wrote:
>>>> El jue, 06-04-2006 a las 17:40 +0200, Andreas Hartmann escribió:
>>>>> Hi Lenya devs,
>>>>>
>>>>> currently, it's not clear which classes+interfaces form
>>>>> the Lenya API (i.e., have to stay backwards compatible
>>>>> and therefore may be used by client code).

> The question is really where to draw the line.

BTW, there's an online book about Java API design:

   http://www.artima.com/interfacedesign/contents.html

More resources:

   http://blogs.msdn.com/kcwalina/archive/2004/09/28/235232.aspx

   http://openide.netbeans.org/tutorial/api-design.html

-- Andreas


-- 
Andreas Hartmann
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
andreas.hartmann@wyona.com                     andreas@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


Re: [1.4] Separate API and Implementation?

Posted by Andreas Hartmann <an...@apache.org>.
Thorsten Scherler wrote:
> El vie, 07-04-2006 a las 13:30 +0200, Andreas Hartmann escribió:
>> Thorsten Scherler wrote:
>>> El jue, 06-04-2006 a las 17:40 +0200, Andreas Hartmann escribió:
>>>> Hi Lenya devs,
>>>>
>>>> currently, it's not clear which classes+interfaces form
>>>> the Lenya API (i.e., have to stay backwards compatible
>>>> and therefore may be used by client code).
>>>>
>>>> Examples are AbstractUsecase and DocumentUsecase:
>>>> Can you extend these classes without the danger of
>>>> incompatible changes in future 1.4.x versions?
>>> I am unsure what to tell you. We have a couple of usecases that extend
>>> this classes. IMO this default implementations should reflect the least
>>> common denominator
>> +1
>>
>>> and as soon as 1.4.x is in the release cycle they
>>> *should* be backwards compatible.
>> IMO AbstractUsecase and DocumentUsecase are general enough
>> to put them into the API.
>>
> 
> agreed, but we still would need an implementation right?

Hmmm, what do you mean? They are abstract implementations
of the Usecase interface ...

The question is really where to draw the line.

IMO some requirements for classes/interfaces in the API are

- it is generic, i.e. it fits all usage patterns
   (nothing like "This only works in certain circumstances ...")

- it can be guaranteed to work in future versions (e.g.,
   it doesn't use internal classes of other products in
   its signature)

- it doesn't reference any classes/interfaces which are
   not part of the API (completeness of the API is required)


Indicators when to put an implementation in the API are:

- it reflects a best practise
- there's no other (sensible) way to do it
- it would be very hard to implement it in the client code
- it's a mere utility to simplify the usage of components

WDYT? What other criteria do apply?

-- Andreas


-- 
Andreas Hartmann
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
andreas.hartmann@wyona.com                     andreas@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


Re: [1.4] Separate API and Implementation?

Posted by Thorsten Scherler <th...@wyona.com>.
El vie, 07-04-2006 a las 13:30 +0200, Andreas Hartmann escribió:
> Thorsten Scherler wrote:
> > El jue, 06-04-2006 a las 17:40 +0200, Andreas Hartmann escribió:
> >> Hi Lenya devs,
> >>
> >> currently, it's not clear which classes+interfaces form
> >> the Lenya API (i.e., have to stay backwards compatible
> >> and therefore may be used by client code).
> >>
> >> Examples are AbstractUsecase and DocumentUsecase:
> >> Can you extend these classes without the danger of
> >> incompatible changes in future 1.4.x versions?
> > 
> > I am unsure what to tell you. We have a couple of usecases that extend
> > this classes. IMO this default implementations should reflect the least
> > common denominator
> 
> +1
> 
> > and as soon as 1.4.x is in the release cycle they
> > *should* be backwards compatible.
> 
> IMO AbstractUsecase and DocumentUsecase are general enough
> to put them into the API.
> 

agreed, but we still would need an implementation right?

> 
> >> I like the approach taken by Avalon/Excalibur:
> >>
> >> - framework/api/src/java
> >> - framework/api/src/test
> >> - framework/impl/src/java
> >> - framework/impl/src/test
> >>
> >> For example: AbstractLogEnabled is part of the API,
> >> AbstractConfiguration is not. A disadvantage of this
> >> approach is that you can't tell whether a class is
> >> part of the API without knowing where it is located
> >> in the source tree. Maybe we can solve this using
> >> package names which contain "impl":
> >>
> >> o.a.lenya.cms.usecase.*
> >> o.a.lenya.cms.usecase.impl.*
> >>
> >>
> >> Modules are another story, but maybe the same concept
> >> can be applied there.
> >>
> >>
> >> WDYT?
> > 
> > Yeah, with this move we as well should harmonize the naming for the
> > implementation classes.
> > 
> > We have now:
> > - Default{api-class-name}.java
> > - {api-class-name}Impl.java
> 
> I'm using Default{*} if I want to point out explicitely
> that the class is just an example implementation, and
> {*}Impl if it is meant to be (more or less) the only
> implementation. But the differences are subtle, and
> it's fine with me to use only one naming convention.
> 

Thanks for the explaning this, I always wondered. ;)

> 
> > - {different-name-then-the-api-class-name}.java
> > 
> > IMO if we agree on 
> >> o.a.lenya.cms.usecase.*
> >> o.a.lenya.cms.usecase.impl.*
> > 
> > Then we should have
> > - o.a.lenya.cms.usecase.*
> >   * {api-class-name}.java
> > - o.a.lenya.cms.usecase.impl.*
> >   * {api-class-name}.java
> 
> IMO this is not very convenient, because you have to use
> explicit package declarations (which is quite verbose),
> and the class name references are ambiguous.
> 
> For example:
> 
>    package org.apache.lenya.cms.impl.Document;
> 
>    class Document implements org.apache.lenya.cms.Document {
> 
>        public org.apache.lenya.cms.Document getParent() {
>            ....
>            org.apache.lenya.cms.Document doc = ...
>            return doc;
>        }
> 
>    }
> 
> In other classes in the *.impl package you might want to
> access *.impl.Document instances directly (not via the
> interface), which is perfectly valid. IMO this makes the
> code hard to understand, because you always have to check
> the imports to know if it's an *.Document or *.impl.Document.
> 
> 
> I'd prefer
> 
>   - o.a.lenya.cms.usecase.*
>     * {api-class-name}.java
>   - o.a.lenya.cms.usecase.impl.*
>     * {api-class-name}Impl.java
> 

Makes perfect sense to me.

+1

> 
> Thanks for your comments!

Thanks for bringing this up.

salu2
-- 
Thorsten Scherler
COO Spain
Wyona Inc.  -  Open Source Content Management  -  Apache Lenya
http://www.wyona.com                   http://lenya.apache.org
thorsten.scherler@wyona.com                thorsten@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


Re: [1.4] Separate API and Implementation?

Posted by Andreas Hartmann <an...@apache.org>.
Thorsten Scherler wrote:
> El jue, 06-04-2006 a las 17:40 +0200, Andreas Hartmann escribió:
>> Hi Lenya devs,
>>
>> currently, it's not clear which classes+interfaces form
>> the Lenya API (i.e., have to stay backwards compatible
>> and therefore may be used by client code).
>>
>> Examples are AbstractUsecase and DocumentUsecase:
>> Can you extend these classes without the danger of
>> incompatible changes in future 1.4.x versions?
> 
> I am unsure what to tell you. We have a couple of usecases that extend
> this classes. IMO this default implementations should reflect the least
> common denominator

+1

> and as soon as 1.4.x is in the release cycle they
> *should* be backwards compatible.

IMO AbstractUsecase and DocumentUsecase are general enough
to put them into the API.


>> I like the approach taken by Avalon/Excalibur:
>>
>> - framework/api/src/java
>> - framework/api/src/test
>> - framework/impl/src/java
>> - framework/impl/src/test
>>
>> For example: AbstractLogEnabled is part of the API,
>> AbstractConfiguration is not. A disadvantage of this
>> approach is that you can't tell whether a class is
>> part of the API without knowing where it is located
>> in the source tree. Maybe we can solve this using
>> package names which contain "impl":
>>
>> o.a.lenya.cms.usecase.*
>> o.a.lenya.cms.usecase.impl.*
>>
>>
>> Modules are another story, but maybe the same concept
>> can be applied there.
>>
>>
>> WDYT?
> 
> Yeah, with this move we as well should harmonize the naming for the
> implementation classes.
> 
> We have now:
> - Default{api-class-name}.java
> - {api-class-name}Impl.java

I'm using Default{*} if I want to point out explicitely
that the class is just an example implementation, and
{*}Impl if it is meant to be (more or less) the only
implementation. But the differences are subtle, and
it's fine with me to use only one naming convention.


> - {different-name-then-the-api-class-name}.java
> 
> IMO if we agree on 
>> o.a.lenya.cms.usecase.*
>> o.a.lenya.cms.usecase.impl.*
> 
> Then we should have
> - o.a.lenya.cms.usecase.*
>   * {api-class-name}.java
> - o.a.lenya.cms.usecase.impl.*
>   * {api-class-name}.java

IMO this is not very convenient, because you have to use
explicit package declarations (which is quite verbose),
and the class name references are ambiguous.

For example:

   package org.apache.lenya.cms.impl.Document;

   class Document implements org.apache.lenya.cms.Document {

       public org.apache.lenya.cms.Document getParent() {
           ....
           org.apache.lenya.cms.Document doc = ...
           return doc;
       }

   }

In other classes in the *.impl package you might want to
access *.impl.Document instances directly (not via the
interface), which is perfectly valid. IMO this makes the
code hard to understand, because you always have to check
the imports to know if it's an *.Document or *.impl.Document.


I'd prefer

  - o.a.lenya.cms.usecase.*
    * {api-class-name}.java
  - o.a.lenya.cms.usecase.impl.*
    * {api-class-name}Impl.java


Thanks for your comments!

-- Andreas


-- 
Andreas Hartmann
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
andreas.hartmann@wyona.com                     andreas@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


Re: [1.4] Separate API and Implementation?

Posted by Thorsten Scherler <th...@wyona.com>.
El jue, 06-04-2006 a las 17:40 +0200, Andreas Hartmann escribió:
> Hi Lenya devs,
> 
> currently, it's not clear which classes+interfaces form
> the Lenya API (i.e., have to stay backwards compatible
> and therefore may be used by client code).
> 
> Examples are AbstractUsecase and DocumentUsecase:
> Can you extend these classes without the danger of
> incompatible changes in future 1.4.x versions?

I am unsure what to tell you. We have a couple of usecases that extend
this classes. IMO this default implementations should reflect the least
common denominator and as soon as 1.4.x is in the release cycle they
*should* be backwards compatible.

> 
> I like the approach taken by Avalon/Excalibur:
> 
> - framework/api/src/java
> - framework/api/src/test
> - framework/impl/src/java
> - framework/impl/src/test
> 
> For example: AbstractLogEnabled is part of the API,
> AbstractConfiguration is not. A disadvantage of this
> approach is that you can't tell whether a class is
> part of the API without knowing where it is located
> in the source tree. Maybe we can solve this using
> package names which contain "impl":
> 
> o.a.lenya.cms.usecase.*
> o.a.lenya.cms.usecase.impl.*
> 
> 
> Modules are another story, but maybe the same concept
> can be applied there.
> 
> 
> WDYT?

Yeah, with this move we as well should harmonize the naming for the
implementation classes.

We have now:
- Default{api-class-name}.java
- {api-class-name}Impl.java
- {different-name-then-the-api-class-name}.java

IMO if we agree on 
> o.a.lenya.cms.usecase.*
> o.a.lenya.cms.usecase.impl.*

Then we should have
- o.a.lenya.cms.usecase.*
  * {api-class-name}.java
- o.a.lenya.cms.usecase.impl.*
  * {api-class-name}.java

wdyt?
-- 
Thorsten Scherler
COO Spain
Wyona Inc.  -  Open Source Content Management  -  Apache Lenya
http://www.wyona.com                   http://lenya.apache.org
thorsten.scherler@wyona.com                thorsten@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


Re: [1.4] [heads-up] Started: Separate API and Implementation?

Posted by Andreas Hartmann <an...@apache.org>.
Michael Wechner wrote:
> Andreas Hartmann wrote:
>>
>> IMO publications shouldn't be allowed to contain Java code
>> at all so that they can be deployed at run-time, but this is
>> a different issue.
> 
> 
> where do you see the problem re publications with Java libs deploying them
> at runtime? You mean because of component registration?

AFAIK the common servlet containers don't support hot-deploying
of new classes in a productive environment - please correct me
if I'm wrong.


> Where do see the difference to modules? E.g. a publication with a 
> specific AccessController? How would you handle that?

That wouldn't be possible. I wouldn't allow publications to add
custom components, but only to access modules which are already
deployed. Then we can ensure that you can deploy any publication
at runtime.

-- Andreas



-- 
Andreas Hartmann
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
andreas.hartmann@wyona.com                     andreas@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


Re: [1.4] [heads-up] Started: Separate API and Implementation?

Posted by Michael Wechner <mi...@wyona.com>.
Andreas Hartmann wrote: 

>
> IMO publications shouldn't be allowed to contain Java code
> at all so that they can be deployed at run-time, but this is
> a different issue.


where do you see the problem re publications with Java libs deploying them
at runtime? You mean because of component registration?

Where do see the difference to modules? E.g. a publication with a 
specific AccessController? How would you handle that?

Michi

>  
>
> -- Andreas
>


-- 
Michael Wechner
Wyona      -   Open Source Content Management   -    Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
michael.wechner@wyona.com                        michi@apache.org
+41 44 272 91 61


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


Re: [1.4] [heads-up] Started: Separate API and Implementation?

Posted by Andreas Hartmann <an...@apache.org>.
Andreas Hartmann wrote:
> Andreas Hartmann wrote:
>> Hi Lenya devs,
>>
>> currently, it's not clear which classes+interfaces form
>> the Lenya API (i.e., have to stay backwards compatible
>> and therefore may be used by client code).
>>
>> Examples are AbstractUsecase and DocumentUsecase:
>> Can you extend these classes without the danger of
>> incompatible changes in future 1.4.x versions?
>>
>>
>> I like the approach taken by Avalon/Excalibur:
>>
>> - framework/api/src/java
>> - framework/api/src/test
>> - framework/impl/src/java
>> - framework/impl/src/test
> 
> I've started to separate the code and changed the build
> process accordingly. Now, the code is compiled in this
> order:
> 
>   1. core API
>   2. modules
>   3. publications
>   4. core implementation

I changed this, now these steps use dedicated classpaths:

1. core API
2. core impl     -> use core API
3. modules       -> use core API
4. publications  -> use core API + modules


-- Andreas

-- 
Andreas Hartmann
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
andreas.hartmann@wyona.com                     andreas@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org


[1.4] [heads-up] Started: Separate API and Implementation?

Posted by Andreas Hartmann <an...@apache.org>.
Andreas Hartmann wrote:
> Hi Lenya devs,
> 
> currently, it's not clear which classes+interfaces form
> the Lenya API (i.e., have to stay backwards compatible
> and therefore may be used by client code).
> 
> Examples are AbstractUsecase and DocumentUsecase:
> Can you extend these classes without the danger of
> incompatible changes in future 1.4.x versions?
> 
> 
> I like the approach taken by Avalon/Excalibur:
> 
> - framework/api/src/java
> - framework/api/src/test
> - framework/impl/src/java
> - framework/impl/src/test

I've started to separate the code and changed the build
process accordingly. Now, the code is compiled in this
order:

   1. core API
   2. modules
   3. publications
   4. core implementation

This has to be changed to a sophisticated dependency management,
i.e. if a module is compiled it should have to declare the
modules it depends on explicitely.

IMO publications shouldn't be allowed to contain Java code
at all so that they can be deployed at run-time, but this is
a different issue.


-- Andreas

-- 
Andreas Hartmann
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
andreas.hartmann@wyona.com                     andreas@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
For additional commands, e-mail: dev-help@lenya.apache.org