Splitting public API interfaces.

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Splitting public API interfaces.

hans_d
Administrator
Hi,

our public API interfaces like Project are used by two different  
groups. One group are the Gradle users when writing there build  
script as well as our plugins. The other group are internal classes  
like BuildConfigurer. Some of the API is only used by the latter  
(e.g. the evaluate method of the Project interface). So I think it  
would be a good idea to add an interface like ProjectInternal, which  
extends Project, for this part of the API.

- Hans

--
Hans Dockter
Gradle Project lead
http://www.gradle.org





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Splitting public API interfaces.

Adam Murdoch-2

Hans Dockter wrote:

> Hi,
>
> our public API interfaces like Project are used by two different
> groups. One group are the Gradle users when writing there build script
> as well as our plugins. The other group are internal classes like
> BuildConfigurer. Some of the API is only used by the latter (e.g. the
> evaluate method of the Project interface). So I think it would be a
> good idea to add an interface like ProjectInternal, which extends
> Project, for this part of the API.
>
I was thinking the same thing as I was writing javadocs (the methods on
Project without javadoc are pretty much the ones I reckon belong elsewhere).

I'd almost add a 3rd group of methods, which are the methods that add
the groovy DSL to the java API - eg Project.task(name, closure). These
are all really just convenience methods for the core API methods.  I
wonder if these belong on another interface which extends Project? That
way another DSL can have its own interface independent of the groovy one.

There are also some methods on the implementation classes of interfaces
like Project which would be good to add to an API interface somewhere -
mainly so they can be documented. These are the groovy DSL variants of
other methods already on the API, eg Project.dependencies(closure) or
createTask(..., closure).


Adam


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Splitting public API interfaces.

hans_d
Administrator

On Aug 8, 2008, at 9:11 AM, Adam Murdoch wrote:

>
> Hans Dockter wrote:
>> Hi,
>>
>> our public API interfaces like Project are used by two different  
>> groups. One group are the Gradle users when writing there build  
>> script as well as our plugins. The other group are internal  
>> classes like BuildConfigurer. Some of the API is only used by the  
>> latter (e.g. the evaluate method of the Project interface). So I  
>> think it would be a good idea to add an interface like  
>> ProjectInternal, which extends Project, for this part of the API.
>>
> I was thinking the same thing as I was writing javadocs (the  
> methods on Project without javadoc are pretty much the ones I  
> reckon belong elsewhere).
>
> I'd almost add a 3rd group of methods, which are the methods that  
> add the groovy DSL to the java API - eg Project.task(name,  
> closure). These are all really just convenience methods for the  
> core API methods.  I wonder if these belong on another interface  
> which extends Project? That way another DSL can have its own  
> interface independent of the groovy one.

I think this is a good idea if we stick to the current design (see my  
comments below). We might call this interface GroovyProject.

>
> There are also some methods on the implementation classes of  
> interfaces like Project which would be good to add to an API  
> interface somewhere - mainly so they can be documented. These are  
> the groovy DSL variants of other methods already on the API, eg  
> Project.dependencies(closure) or createTask(..., closure).

Wouldn't be GroovyProject the place to put them (for the Project  
methods)?


In the beginning we had simply a DefaultTask and a DefaultProject  
class to implement our Project and Task interface. Then we decided  
that to improve performance and for some other reasons we want to  
implement as much as possible in Java. We did this pretty much in a  
rush. The current state is not as concise as I would like it to be.

One may define three layers for this space:

1.) Java classes which use only other java classes
2.) Java classes which use also Groovy classes
3.) Groovy classes

To objective for separating the layers 1.) from 2.) and 3.) is to  
separate the pure Java core from a specific DSL. This separation adds  
complexity to the design (e.g. introduction of Action classes)  
although right now we have only one DSL language. We don't know when  
we start to develop an engine for another DSL language and what  
exactly the requirements for this would be. I think the current  
separation smells a little bit like 'speculative generality'.  I'm  
wondering if we should merge this layers again. Also this layerign is  
only partly implemented.

The objective for separating the layers 2.) and 3.) is to have as  
much functionality as possible in Java. Only Groovy specific stuff  
goes into a Groovy class (like the methodMissing method).  
Theoretically you could implement layer 3 also in Java by extending  
GroovyObjectSupport or implementing GroovyObject. But I have  
encountered a Groovy bug when doing so (I haven't reported it yet).  
Therefore right now we have to do layer 3 in Groovy but in the future  
we could merge 2.) and 3.).

- Hans

--
Hans Dockter
Gradle Project lead
http://www.gradle.org





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Splitting public API interfaces.

hans_d
Administrator
In reply to this post by Adam Murdoch-2

On Aug 8, 2008, at 9:11 AM, Adam Murdoch wrote:

>
> Hans Dockter wrote:
>> Hi,
>>
>> our public API interfaces like Project are used by two different  
>> groups. One group are the Gradle users when writing there build  
>> script as well as our plugins. The other group are internal  
>> classes like BuildConfigurer. Some of the API is only used by the  
>> latter (e.g. the evaluate method of the Project interface). So I  
>> think it would be a good idea to add an interface like  
>> ProjectInternal, which extends Project, for this part of the API.
>>
> I was thinking the same thing as I was writing javadocs (the  
> methods on Project without javadoc are pretty much the ones I  
> reckon belong elsewhere).
>

I have added some more javadoc to the project interface. Those two  
methods definitely belong elsewhere:

Project evaluate();

BuildScriptProcessor getBuildScriptProcessor();

All the other ones I think should be offered to the build script.

- Hans

--
Hans Dockter
Gradle Project lead
http://www.gradle.org





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Splitting public API interfaces.

Adam Murdoch-2
In reply to this post by hans_d


Hans Dockter wrote:

>
> On Aug 8, 2008, at 9:11 AM, Adam Murdoch wrote:
>
>>
>> Hans Dockter wrote:
>>> Hi,
>>>
>>> our public API interfaces like Project are used by two different
>>> groups. One group are the Gradle users when writing there build
>>> script as well as our plugins. The other group are internal classes
>>> like BuildConfigurer. Some of the API is only used by the latter
>>> (e.g. the evaluate method of the Project interface). So I think it
>>> would be a good idea to add an interface like ProjectInternal, which
>>> extends Project, for this part of the API.
>>>
>> I was thinking the same thing as I was writing javadocs (the methods
>> on Project without javadoc are pretty much the ones I reckon belong
>> elsewhere).
>>
>> I'd almost add a 3rd group of methods, which are the methods that add
>> the groovy DSL to the java API - eg Project.task(name, closure).
>> These are all really just convenience methods for the core API
>> methods.  I wonder if these belong on another interface which extends
>> Project? That way another DSL can have its own interface independent
>> of the groovy one.
>
> I think this is a good idea if we stick to the current design (see my
> comments below). We might call this interface GroovyProject.
>
>>
>> There are also some methods on the implementation classes of
>> interfaces like Project which would be good to add to an API
>> interface somewhere - mainly so they can be documented. These are the
>> groovy DSL variants of other methods already on the API, eg
>> Project.dependencies(closure) or createTask(..., closure).
>
> Wouldn't be GroovyProject the place to put them (for the Project
> methods)?
>
It would be.  I might add them to Project (with javadoc, of course)
until we decide what to do with the groovy stuff, so they can be documented.

> In the beginning we had simply a DefaultTask and a DefaultProject
> class to implement our Project and Task interface. Then we decided
> that to improve performance and for some other reasons we want to
> implement as much as possible in Java. We did this pretty much in a
> rush. The current state is not as concise as I would like it to be.
>
> One may define three layers for this space:
>
> 1.) Java classes which use only other java classes
> 2.) Java classes which use also Groovy classes
> 3.) Groovy classes
>
> To objective for separating the layers 1.) from 2.) and 3.) is to
> separate the pure Java core from a specific DSL. This separation adds
> complexity to the design (e.g. introduction of Action classes)
> although right now we have only one DSL language. We don't know when
> we start to develop an engine for another DSL language and what
> exactly the requirements for this would be. I think the current
> separation smells a little bit like 'speculative generality'.  I'm
> wondering if we should merge this layers again. Also this layerign is
> only partly implemented.
>
What would the merged layers look like? What would you change?


Adam

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Splitting public API interfaces.

hans_d
Administrator

On Aug 9, 2008, at 12:41 PM, Adam Murdoch wrote:

>
>
> Hans Dockter wrote:
>>
>> On Aug 8, 2008, at 9:11 AM, Adam Murdoch wrote:
>>
>>>
>>> Hans Dockter wrote:
>>>> Hi,
>>>>
>>>> our public API interfaces like Project are used by two different  
>>>> groups. One group are the Gradle users when writing there build  
>>>> script as well as our plugins. The other group are internal  
>>>> classes like BuildConfigurer. Some of the API is only used by  
>>>> the latter (e.g. the evaluate method of the Project interface).  
>>>> So I think it would be a good idea to add an interface like  
>>>> ProjectInternal, which extends Project, for this part of the API.
>>>>
>>> I was thinking the same thing as I was writing javadocs (the  
>>> methods on Project without javadoc are pretty much the ones I  
>>> reckon belong elsewhere).
>>>
>>> I'd almost add a 3rd group of methods, which are the methods that  
>>> add the groovy DSL to the java API - eg Project.task(name,  
>>> closure). These are all really just convenience methods for the  
>>> core API methods.  I wonder if these belong on another interface  
>>> which extends Project? That way another DSL can have its own  
>>> interface independent of the groovy one.
>>
>> I think this is a good idea if we stick to the current design (see  
>> my comments below). We might call this interface GroovyProject.
>>
>>>
>>> There are also some methods on the implementation classes of  
>>> interfaces like Project which would be good to add to an API  
>>> interface somewhere - mainly so they can be documented. These are  
>>> the groovy DSL variants of other methods already on the API, eg  
>>> Project.dependencies(closure) or createTask(..., closure).
>>
>> Wouldn't be GroovyProject the place to put them (for the Project  
>> methods)?
>>
> It would be.  I might add them to Project (with javadoc, of course)  
> until we decide what to do with the groovy stuff, so they can be  
> documented.

Good idea.

>
>> In the beginning we had simply a DefaultTask and a DefaultProject  
>> class to implement our Project and Task interface. Then we decided  
>> that to improve performance and for some other reasons we want to  
>> implement as much as possible in Java. We did this pretty much in  
>> a rush. The current state is not as concise as I would like it to be.
>>
>> One may define three layers for this space:
>>
>> 1.) Java classes which use only other java classes
>> 2.) Java classes which use also Groovy classes
>> 3.) Groovy classes
>>
>> To objective for separating the layers 1.) from 2.) and 3.) is to  
>> separate the pure Java core from a specific DSL. This separation  
>> adds complexity to the design (e.g. introduction of Action  
>> classes) although right now we have only one DSL language. We  
>> don't know when we start to develop an engine for another DSL  
>> language and what exactly the requirements for this would be. I  
>> think the current separation smells a little bit like 'speculative  
>> generality'.  I'm wondering if we should merge this layers again.  
>> Also this layerign is only partly implemented.
>>
> What would the merged layers look like? What would you change?

We would remove the interfaces DagAction, ProjectAction and  
TaskAction and the respective methods like Task.doFirst(TaskAction),  
etc .... and we would only work with Closures and use only methods  
like doFirst(Closure action). AbstractTask would merge into the class  
DefaultTask. AbstractProject would merge into DefaultProject (which  
would then be a Java class) as soon as the Groovy bug mentioned above  
is fixed. But I'm not sure yet if this is a good idea.

- Hans

--
Hans Dockter
Gradle Project lead
http://www.gradle.org





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Splitting public API interfaces.

hans_d
Administrator

>
>>
>>> In the beginning we had simply a DefaultTask and a DefaultProject  
>>> class to implement our Project and Task interface. Then we  
>>> decided that to improve performance and for some other reasons we  
>>> want to implement as much as possible in Java. We did this pretty  
>>> much in a rush. The current state is not as concise as I would  
>>> like it to be.
>>>
>>> One may define three layers for this space:
>>>
>>> 1.) Java classes which use only other java classes
>>> 2.) Java classes which use also Groovy classes
>>> 3.) Groovy classes
>>>
>>> To objective for separating the layers 1.) from 2.) and 3.) is to  
>>> separate the pure Java core from a specific DSL. This separation  
>>> adds complexity to the design (e.g. introduction of Action  
>>> classes) although right now we have only one DSL language. We  
>>> don't know when we start to develop an engine for another DSL  
>>> language and what exactly the requirements for this would be. I  
>>> think the current separation smells a little bit like  
>>> 'speculative generality'.  I'm wondering if we should merge this  
>>> layers again. Also this layerign is only partly implemented.
>>>
>> What would the merged layers look like? What would you change?
>
> We would remove the interfaces DagAction, ProjectAction and  
> TaskAction and the respective methods like Task.doFirst
> (TaskAction), etc .... and we would only work with Closures and use  
> only methods like doFirst(Closure action). AbstractTask would merge  
> into the class DefaultTask. AbstractProject would merge into  
> DefaultProject (which would then be a Java class) as soon as the  
> Groovy bug mentioned above is fixed. But I'm not sure yet if this  
> is a good idea.
>

I don't think any longer that this is a good idea. I see two use  
cases were this strict layering is beneficial.

Embedded Usage: I love tools like Jetty or Ivy which are usually  
driven by some descriptor files like web.xml or ivy.xml, but also  
expose their functionality via an API. This usually does open up  
unanticipated use cases. And I think there shouldn't be a groovy  
requirement for this usage scenario.

Offering a Java Build Script Engine: Although Groovy is usually the  
most convenient build script engine an additional Java build script  
engine has some benefits if:
- performance and startup requirements are very strict
- for whatever reason, only Java is possible to use (e.g. company  
policy)
- very useful for performance profiling (no dynamic dispatches).
The biggest pain point of a Java build script engine is probably the  
lack of an Ant Builder. Using Ant via its API is pretty inconvenient.  
But that is another story.

- Hans

--
Hans Dockter
Gradle Project lead
http://www.gradle.org





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email