tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ulrich Stärk <...@spielviel.de>
Subject Re: [CONF] Apache Tapestry > Developer Bible
Date Fri, 01 Oct 2010 07:27:06 GMT

Can you tell me your confluence user name, I'll add you to the tapestry-committers group.


Am 01.10.2010 um 03:27 schrieb Josh Canfield <joshcanfield@gmail.com>:

> Ah. I thought I needed my Apache account. I'm signed up for cwiki now and
> I'll just fix it next time! :)
> On Sep 30, 2010 5:58 PM, "Kalle Korhonen" <kalle.o.korhonen@gmail.com>
> wrote:
>> I see - but cwiki accounts are separate from Apache accounts, so just sign
> up.
>> 
>> Kalle
>> 
>> 
>> On Thu, Sep 30, 2010 at 5:52 PM, Josh Canfield <joshcanfield@gmail.com>
> wrote:
>>> Yep, but I'm still waiting for my account...
>>> On Sep 30, 2010 4:52 PM, "Kalle Korhonen" <kalle.o.korhonen@gmail.com>
>>> wrote:
>>>> Fixed. Faster to fix yourself than send an email, no?
>>>> 
>>>> Kalle
>>>> 
>>>> 
>>>> On Thu, Sep 30, 2010 at 3:31 PM, Josh Canfield <joshcanfield@gmail.com>
>>> wrote:
>>>>> typo in Copyright section:  "try to check the coyright date"
>>>>> 
>>>>> On Thu, Sep 30, 2010 at 2:49 PM, <confluence@apache.org> wrote:
>>>>> 
>>>>>>   Developer Bible<
>>> https://cwiki.apache.org/confluence/display/TAPESTRY/Developer+Bible>
> Page
>>>>>> *added* by Howard M. Lewis Ship<
>>> https://cwiki.apache.org/confluence/display/~hlship>
>>>>>> 
>>>>>> This is a semi-random outpouring of thoughts related to being a
> Tapestry
>>>>>> committer.
>>>>>> IDE IntelliJ
>>>>>> 
>>>>>> It's a free license for all committers and it's just better. Yes,
the
>>> first
>>>>>> few days
>>>>>> can be an unpleasant fumble because everything is almost, but not
> quite,
>>>>>> familiar. Pretty soon you'll love IDEA and
>>>>>> recognize that Eclipse has been bending you over and doing unspeakable
>>>>>> things.
>>>>>> 
>>>>>> There are shared code formatting settings in
>>> *<support/idea-settings.jar*>.
>>>>>> This will prevent
>>>>>> unexpected conflicts due to formatting.
>>>>>> Eclipse
>>>>>> 
>>>>>> Howard uses this ... because he can't manage to switch IDEs constantly
>>> (he
>>>>>> uses Eclipse for training). Lately
>>>>>> its gotten better.
>>>>>> Copyrights
>>>>>> 
>>>>>> All source files should have a copyright comment on top, except where
>>> such
>>>>>> a comment
>>>>>> would interfere with its behavior. For example, component template
> files
>>>>>> omit the comment.
>>>>>> 
>>>>>> The year on the copyright should be updated as a file changes. As
you
>>> are
>>>>>> reviewing your changes
>>>>>> before checking them in, try to check the coyright date, and add
the
>>>>>> current year to the list if not
>>>>>> present.
>>>>>> Commit Messages
>>>>>> 
>>>>>> Always provide a commit message. I generally try to work off the
JIRA,
>>> so
>>>>>> my commit message is often:
>>>>>> 
>>>>>> TAP5-1234: Make the Foo Widget more Ajax-tastic!
>>>>>> 
>>>>>> It is *very important* to include the JIRA issue id in the commit.
> This
>>> is
>>>>>> used in many places:
>>>>>> JIRA links issues to the SVN commits for that issue (very handy for
>>> seeing
>>>>>> what changed
>>>>>> as part of a bug fix). The Hudson CI server does as well, and will
>>> actually
>>>>>> link SVN commits to issues after
>>>>>> succesfully building.
>>>>>> JIRA Procedures
>>>>>> 
>>>>>> All Tapestry committers should be registerred with JIRA and part
of
> the
>>>>>> tapestry-developers JIRA group.
>>>>>> 
>>>>>> I work the following JIRA list: JIRA Work Queue<
>>> 
> https://issues.apache.org/jira/secure/IssueNavigator.jspa?mode=hide&requestId=12311597
>>>> 
>>>>>> .
>>>>>> 
>>>>>> Ideally, we would always work top priortity to low priority. I
> (Howard)
>>>>>> sometimes jump out of order,
>>>>>> if there's something cool to work on that fits in an available time
>>> slot.
>>>>>> Alternately, you are always
>>>>>> allowed to change the priority of a bug before or as you work it.
>>>>>> Starting work
>>>>>> 
>>>>>> When you start to work on an issue, make sure it is *assigned to
you*
>>> and
>>>>>> use the *start progress*
>>>>>> option.
>>>>>> 
>>>>>> I often add comments about the state of the fix, or the challenges
in
>>>>>> creating a fix. This often spurs the Issue's adder to
>>>>>> provide more details.
>>>>>> 
>>>>>> I often update the issue description to make it more legible and
more
>>>>>> precise, i.e., "NPE in CheckUpdates"
>>>>>> might become "NullPointerException when checking for updates to files
>>> that
>>>>>> have been deleted". Verbose is good.
>>>>>> Closing bugs
>>>>>> 
>>>>>> Is it a bug fix without tests? *No.* In some cases, I write new tests
> to
>>>>>> prove that an issue is not valid and
>>>>>> then leave the tests in place – then close the bug as invalid.
>>>>>> 
>>>>>> A good plan is to write a test that fails then work the code until
the
>>> test
>>>>>> passes.
>>>>>> I'm also surprised by how often code works in a unit test but fails
>>>>>> unexpectedly in an integration test.
>>>>>> As the G-Man says *"Expect unforseen consequences"*.
>>>>>> 
>>>>>> When you check in a fix, you should *close* the issue and make sure
> the
>>> *fix
>>>>>> release* is correct.
>>>>>> 
>>>>>> We're playing fast and loose – a better procedure would be to mark
the
>>> bug
>>>>>> resolved and verify
>>>>>> the fix before closing it. That's ok, we have a community to double
>>> check
>>>>>> our work .
>>>>>> 
>>>>>> For anything non-trivial, wait for the Hudson CI server to build.
It
>>>>>> catches a lot of things ... such as
>>>>>> files that were not added to SVN. And even IntelliJ has a bit of
> trouble
>>>>>> with wildly refactored code.
>>>>>> Hudson will catch all that.
>>>>>> Invalid issues and duplicates
>>>>>> 
>>>>>> Always provide comments about why_ an issue is invalid (*"A Ruby
>>>>>> implementation of Tapestry is out of scope for the project."*), or
at
>>>>>> least, a link to the duplicate issues.
>>>>>> 
>>>>>> Close the issue but *make sure the fix release is blank*. Otherwise,
> the
>>>>>> issue _will be listed
>>>>>> in the release notes_, which we don't want.
>>>>>> Copyrights
>>>>>> 
>>>>>> The ASF copyright must appear on all Java source files. Technically
it
>>>>>> should appear on all non-binary
>>>>>> files in the repository.
>>>>>> 
>>>>>> As you make changes to files, update the copyright to add the current
>>> year
>>>>>> to the list. The goal is that the copyright
>>>>>> notice includes the year in which files change. When creating a new
>>> file,
>>>>>> don't back date the copyright year ... starwith the current year.
Try
>>> not to
>>>>>> change the copyright year on files that haven't actually changed.
>>>>>> 
>>>>>> IntelliJ has a great comparison view: Cmd-9 to see the local changes,
>>> the
>>>>>> Cmd-D to see the differences.
>>>>>> I whip through the changes (using Cmd-forward arrow) and make sure
>>>>>> copyrights are up to date as I review the changes
>>>>>> prior to a commit.
>>>>>> Public vs. Private/Internal
>>>>>> 
>>>>>> This is a real big deal. As long as code is in the internal package,
> we
>>>>>> have a high degree of carte-blanche
>>>>>> to change it. As soon as code is public, we become handcuffed to
>>> backwards
>>>>>> compatibility.
>>>>>> 
>>>>>> *Interfaces are public, implementations are private*. You can see
this
>>> is
>>>>>> the bulk of the code, where
>>>>>> org.apache.tapestry5.services is almost all interfaces and the
>>>>>> implementations are
>>>>>> in org.apache.tapestry5.internal.services.
>>>>>> 
>>>>>> Many more services have both the interface and the implementation
in
>>>>>> org.apache.tapestry5.internal.services.
>>>>>> 
>>>>>> We absolutely *do not* want to make Page or ComponentPageElement
> public.
>>>>>> You will often see
>>>>>> public service facades that take a page name as a method parameter,
>>>>>> and convert it to a page instance before invoking methods
>>>>>> on internal services.
>>>>>> Evolving Components
>>>>>> 
>>>>>> We do not have a specific plan for this yet. Future Tapestry 5 will
> add
>>>>>> features to allow clean renames
>>>>>> of parameters, and a way to deprecated and eventually remove
> components.
>>>>>> Evolving Interfaces
>>>>>> 
>>>>>> Tapestry uses interfaces quite extensively.
>>>>>> 
>>>>>> Interfaces fall into two categories: service interfaces called by
user
>>>>>> code, and interfaces implemented by user code.
>>>>>> 
>>>>>> Internal interfaces may be changed at any time. That's why so much
is
>>> kept
>>>>>> internal.
>>>>>> Service Interfaces
>>>>>> 
>>>>>> New methods may be added if absolutely necessary, but this should
be
>>>>>> avoided if at all possible. Don't forget
>>>>>> the @since Javadoc annotation.
>>>>>> 
>>>>>> Consider having a stable public facade service whose implementation
>>> calls
>>>>>> into one or more internal service.
>>>>>> User Interfaces
>>>>>> 
>>>>>> These should be frozen, no changes once released. Failure to do so
>>> causes
>>>>>> *non-backwards compatible upgrade problems*;
>>>>>> that is, classes that implement the (old) interface are suddenly
>>> invalid,
>>>>>> missing methods from the (new) interface.
>>>>>> 
>>>>>> Consider introducing a new interface that extends the old one and
adds
>>> new
>>>>>> methods. Make sure you support both.
>>>>>> 
>>>>>> You can see this with ServiceDef and ServiceDef2 (which extends
>>>>>> ServiceDef). Yes this can be a bit ugly.
>>>>>> 
>>>>>> I actually have utility methods that convert from ServiceDef to
>>>>>> ServiceDef2, adding a wrapper implementation around
>>>>>> a ServiceDef instance if necessary:
>>>>>> Use of @since
>>>>>> 
>>>>>> When adding new classes or interface, or adding new methods to
> existing
>>>>>> types, add an @since Javadoc comment.
>>>>>> 
>>>>>> Use the complete version number of the release in which the type
or
>>> method
>>>>>> was added: i.e., *@since 5.1.0.3*.
>>>>>> Code Style
>>>>>> 
>>>>>> Yes, at one time I (Howard) used leading underscores for field names.
>>> I've
>>>>>> since changed my mind, but
>>>>>> I unfortunately infected other people; please try to make your code
>>> blend
>>>>>> in when modifying existing source.
>>>>>> 
>>>>>> Long ago, Tapestry (3) code used the regrettable
>>> "leading-I-on-interfaces"
>>>>>> style. Don't do that. Everything's an interface.
>>>>>> 
>>>>>> I prefer braces on a new line (and thus, open braces lined up with
> close
>>>>>> braces), so that's what the default
>>>>>> code formatting is set up for. I sometimes omit braces for trivial
if
>>>>>> statements, such as {{ if (!test) return; }}.
>>>>>> 
>>>>>> I use a lot of vertical whitespace to break methods into logical
>>> sections.
>>>>>> 
>>>>>> We're coding Java, not Pascal; I'd much rather see a few checks early
> on
>>>>>> with quick returns or exceptions than
>>>>>> have ten-levels deep block nesting just so a method can have a single
>>>>>> return statement. In other words,
>>>>>> *else considered harmful*. Low code complexity is better, more
> readable,
>>>>>> more maintainable code.
>>>>>> 
>>>>>> I don't bother alphabetizing things, because I have an IDE that lets
> me
>>>>>> jump around easily.
>>>>>> 
>>>>>> *Final is the new private.* Final fields are great for multi-threaded
>>>>>> code. Especially when creating
>>>>>> service implementations with dependencies, store those dependencies
> into
>>>>>> final fields. Once we're all running
>>>>>> on 100 core workstations, you'll thank me. Seriously, Java's memory
>>> model
>>>>>> is seriously twisted stuff, and
>>>>>> assigning to a non-final field from a constructor opens up a tiny
> window
>>> of
>>>>>> non-thread safety.
>>>>>> Comments
>>>>>> 
>>>>>> Comments are overwhelmingly important. Try to capture the *why* of
a
>>> class
>>>>>> or method. Add lots
>>>>>> of links, to code that will be invoked by the method, to related
> methods
>>> or
>>>>>> classes, and so forth. For instance,
>>>>>> I'll often have an annotation, a worker class for the annotation,
and
> a
>>>>>> related service all cross-linked.
>>>>>> 
>>>>>> Comment the *interfaces* and don't get worked up on the
>>> *implementations*.
>>>>>> Javadoc does a perfectly
>>>>>> good job of copying interface comments to implementations, so this
> falls
>>>>>> under the *Dont Repeat Yourself*
>>>>>> guideline.
>>>>>> 
>>>>>> Be very careful about documenting what methods can accept null, and
> what
>>>>>> methods may return null. Generally
>>>>>> speaking, people will assume that null is not allowed for parameter
> and
>>>>>> method will never return null, unless
>>>>>> it is explicitly documented that null is allowed (or potentially
>>> returned).
>>>>>> Documentation
>>>>>> 
>>>>>> Try and keep the documentation up-to date as you make changes; it
is
>>> *much
>>>>>> * harder to do so later. This is now much easier using the Confluence
>>> wiki
>>>>>> (you're reading it ).
>>>>>> 
>>>>>> Documentation is the *#1 criticism* of Tapestry!
>>>>>> Class and Method Naming Conventions
>>>>>> 
>>>>>> aming things is hard. Names that make sense to one person won't to
>>> another.
>>>>>> 
>>>>>> hat being said, I've tried to be somewhat consistent with naming.
Not
>>>>>> perfectly.
>>>>>> Factory, Creator
>>>>>> 
>>>>>> A factory class creates new objects. Methods will often be prefixed
> with
>>>>>> "create"
>>>>>> or "new". Don't expect a Factory to cache anything, it just creates
> new
>>>>>> things.
>>>>>> Source
>>>>>> 
>>>>>> A source is a level up from a Factory. It *may* combine multiple
>>> factories
>>>>>> together.
>>>>>> It *usually* will cache the result. Method are often prefixed with
>>> "get".
>>>>>> Find vs. Get
>>>>>> 
>>>>>> For methods: A "find" prefix indicates that a non-match is valid
and
>>> null
>>>>>> may be returned.
>>>>>> A "get" prefix indicates that a non-match is invalid and an exception
>>> will
>>>>>> be thrown
>>>>>> in that case (and null will never be returned).
>>>>>> Contribution
>>>>>> 
>>>>>> A data object usually associated with a Tapestry IoC service's
>>>>>> configuration.
>>>>>> Filter
>>>>>> 
>>>>>> Part of a pipeline, where there's an associated main interface,
>>>>>> and the Filter wraps around that main interface. Each main interface
>>>>>> method is duplicated in the Filter, with an extra parameter used
>>>>>> to chain the interface.
>>>>>> Manager
>>>>>> 
>>>>>> Often a wrapper around a service configuration, it provides access
>>>>>> to the contributed values (possibly after some transformation).
>>>>>> To
>>>>>> 
>>>>>> A method prefix that indicates a conversion or coersion from one
type
> to
>>>>>> another. I.e., toUserPresentable().
>>>>>> Worker
>>>>>> 
>>>>>> An object that peforms a specific job. Workers will be stateless,
but
>>> will
>>>>>> be passed
>>>>>> a stateful object to perform some operation upon.
>>>>>> Builder
>>>>>> 
>>>>>> An object whose job is to create other objects, typically in the
> context
>>> of
>>>>>> creating a core service implementation for a Tapestry IoC service
> (such
>>> as
>>>>>> PipelineBuilder
>>>>>> or ChainBuilder).
>>>>>> Support
>>>>>> 
>>>>>> An object that provides supporting operations to other objects; this
> is
>>> a
>>>>>> kind of "loose aggregation".
>>>>>> Parameters
>>>>>> 
>>>>>> A data object that holds a number of related values that would
> otherwise
>>> be
>>>>>> separate
>>>>>> parameter values to a method. This tends to streamline code
> (especially
>>>>>> when using
>>>>>> a Filter interface) and allows the parameters to be evolved without
>>>>>> changing the method signature.
>>>>>> Strategy
>>>>>> 
>>>>>> An object that "plugs into" some other code, allowing certain
> decisions
>>> to
>>>>>> be deferred
>>>>>> to the Strategy. Often a Strategy is selected based on the type of
> some
>>>>>> object
>>>>>> being operated upon.
>>>>>> Context
>>>>>> 
>>>>>> Captures some stateful information that may be passed around between
>>>>>> stateless services.
>>>>>> Constants
>>>>>> 
>>>>>> A non-instantiable class that contains public static fields that
are
>>>>>> referenced in multiple places.
>>>>>> Hub
>>>>>> 
>>>>>> An object that allows listeners to be registered. Often includes
a
>>> method
>>>>>> prefixed with "trigger"
>>>>>> that will send notifications to listeners.
>>>>>> Implement toString()
>>>>>> 
>>>>>> Objects that are exposed to user code should generally implement
a
>>>>>> meaningful toString() method.
>>>>>> And that method should be tested.
>>>>>> Subclassing
>>>>>> 
>>>>>> You'll notice there isn't a lot of inheritance in Tapestry. Given
the
>>>>>> function of the IoC container,
>>>>>> it is much more common to use some variation of *aggregation* rather
>>> than
>>>>>> *inheritance*.
>>>>>> 
>>>>>> Where subclassing exists, the guideline for constructor parameters
is:
>>> the
>>>>>> subclass should include all
>>>>>> the constructor parameters of the superclass, in the same positions.
>>> Thus
>>>>>> subclass constructor parameters
>>>>>> are appended to the list of super-class constructor parameters.
>>>>>>  Change Notification Preferences<
>>> https://cwiki.apache.org/confluence/users/viewnotifications.action>
>>>>>> View Online<
>>> https://cwiki.apache.org/confluence/display/TAPESTRY/Developer+Bible>
>>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> --
>>>>> --
>>>>> http://www.bodylabgym.com - a private, by appointment only, one-on-one
>>>>> health and fitness facility.
>>>>> --
>>>>> http://www.ectransition.com - Quality Electronic Cigarettes at a
>>> reasonable
>>>>> price!
>>>>> --
>>>>> TheDailyTube.com. Sign up and get the best new videos on the internet
>>>>> delivered fresh to your inbox.
>>>>> 
>>>> 
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>>>> For additional commands, e-mail: dev-help@tapestry.apache.org
>>>> 
>>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: dev-help@tapestry.apache.org
>> 

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


Mime
View raw message