When coding, we (developers) often need to code repetitive things, especially when implementing some patterns: think about delegation with a 15-methods class, or about a visitor interface that must visit a 35-nodes DOM, or any serialization (SQL, XML) method for a 20-fields bean…
This is where patterns and code generation can help. Code generation produces consistent, ready-to-compile code, while patterns define the developer –intention- which is very helpful for the code generation. As a developer I do not like to write repetitive code, it takes (too) much time and is error-prone. If I were given some pattern tags that would drive instant code generation that respects my code, I would save time.
In addition, patterns help in documenting code. As a developer I often spend (too) much time to write good javadoc documentation; if I were offered some more pattern tags I will be able to describe my intention with words, not sentences: I will save time again.
As there is nearly no real-world feedback on this topic, Patternity is also an attempt to get something working in order to gain such feedback.
You write normal javadoc comments, and when you like you add pattern tags, along with a few (optional) parameters and comment. Then you run the Patternity doclet (as a standalone batch command or automated in the build process) and you get the generated code (typically new methods) directly written in your code. You can run Patternity as often as you like at no risk for your code or for the already generated code. You can modify the generated code, your modification will remain when you run Patternity again.
To get the pattern-specific documentation added to your javadoc comment, you need to add the doclet into your javadoc process.
Patternity uses the javadoc engine that builds a complete document object model (DOM) of the packages, classes, methods and fields and their tags.
Patterns implement the Pattern interface that allows them to be registered in Patternity for one or several tags, DOM element, tag parameters… When these conditions are met in the javadoc DOM, the corresponding pattern is retrieved, set up with parameters, javadoc DOM and the output writer. Finally the pattern is started, and is then responsible for generating the code to the writer using the javadoc DOM data. In particular patterns must ensure that the generated code must ALWAYS compiles with no error at first try. This involves checking that a method to be generated does not already exists for example.
A first attempt was made using a JavaCC-generated tree parser-builder with a unparsed visitor to insert the generated code into the source code. It works well, but it is not worth the complexity when the code can also be inserted with simple java.io classes, as it is now.
Because the pattern tags are best given to field or method it enables Patternity to deduce many information such as the role of this class in the pattern, and the role of some other classes or interfaces related to this pattern, with no need for the developer to specify these information again.
A pattern is able to find some of its key participants, through a field or a method, or common interface. It can also validate the role names, the also-known-as names and its specific parameters. Thus each pattern is responsible for handling both its code generation and documentation aspects through template methods.
- Field and method tags benefits from the knowledge of the field or method itself, thus it prevents the developer from specifying too many information (it saves time and reduces errors)
- Adding tags at the field and method level also helps for pattern automatic implementation since many patterns rely on field or method as implementation starting point
- Also, field and method tags can access the modifiers (private, public…) so that patterns may also be hidden or visible depending on the javadoc options. This is consistent because for example a Façade pattern may not need to be documented in an end-user documentation (when the corresponding fields need not be either).
Not all participants in a pattern can have pattern-specific documentation because they are not all involved in the same active way. For example, in a Proxy, the Proxy class is active –the pattern exists because of it, and this class has no meaning outside of this pattern. On the other hand, the Real Subject is not even aware of its participation in the pattern, and does not depend at all from the pattern. Thus, to give such class a pattern-specific documentation may be simply wrong.
Patternity will always remain simple, it will not become a full-featured EDI, or a do-everything product. However any other project or product can embeds Patternity as a module.