typo in Copyright section: "try to check the coyright date" On Thu, Sep 30, 2010 at 2:49 PM, <[email protected]> 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.
