This is a draft AND a proposal. This, in no way, constitutes a document of how we're currently naming things. Rather, it's a proposal of where we'd like to go.
There are a bunch of places where our naming (classes, packages, ...) is rather inconsistent. This document proposes a convention, to be taken with a grain of salt, to attempt to consolidate our code base.
Whenever you feel unsatisfied with an existing name, or are writing new code, have a look here.
Modules & apps
Source code repository name and location
Tags and branches
info.magnolia.*? : the discussion here is about whether the ".cms" subpackage is relevant. We started adding packages outside of it a while back, without much thinking about it. Now, we see how relevant it might have been - stuff under
.cmsrelates to the CMS product. Unfortunately, this thought is not consistent with reality. There are "generic" packages under
.cms, and there are product-specific packages outside.
.setupsubpackages are used for ModuleVersionHandler classes, tasks, etc.
- Modules should not use
info.magnolia.module.x, but use
info.magnolia.xinstead. The former "clashes" with core's
info.magnolia.modulepackages which contains ModuleManager and other base component of the module and version handling base systems.
How to choose a new package name
Now that the location of your new package is clarified, how should you name your package(s) ?
- Group by functionality (
.upload), not by type (
.dialogs), . Objects that "use" each other are packaged together. This allows for less public APIs, which in turns eases testability, maintenance and stability.
- ? interfaces outside implementation packages (i.e
There are usually good reasons to give a certain name to a class. Here we're attempting to clarify those reasons and provide some guidelines for consistency.
to be completed: in many cases, we're going to be referring to a known pattern. It would help to provide links to GoF pattern definitions (or other, more modern references, for example Martin Fowler's wiki).
Abstract, base, impl, default, ...
FooImpl: when you have an interface, implemented by this component, and there is no evidence that a different implementation will be needed.
DefaultFoo: when you have an interface, implemented by this component, and it is likely that different implementation could be needed for certain projects or tasks.
Also see http://blog.joda.org/2011/08/implementations-of-interfaces-prefixes.html
Factories, providers, ...
FooAdapter(this is perhaps PicoContainer-specific)
Strategies and policies
- Module configuration classes:
Naming of the test classes
Unit Tests: Tests for a class should be placed in a class with the same name and the postfix Test. Like for
FileSystemOrigin there should be a
Naming of test cases
Try to use DAMP in tests, especially for test method names. Avoid tests like
foo() is a method of the object under test. Try rather a pattern like
fooDoesThisWhenThat() (see the verb in there?). It highlights the expected behavior and the conditions of the test.
Note that we've been using JUnit 4 long enough, not to bother with the test prefix anymore (dear
@Test annotation). Do feel free to align this when touching an older test class; however avoid having a mix of both.
Here are some good and bad examples:
@Test registerForChangesTriggersCallbackForGivenPattern() @Test newResourcePathThrowsExceptionWhenGivenPathIsNotBelowRoot()
@Test testRegisterForChanges() @Test newResourcePathWithWrongRootPath()