... h3. The fluent and convenient side of the _Java API for KML_ The code of [KML in the Java world#Listing4|jak:KML in the Java world#listing4] seems a bit awkward and verbose. Additionally, the API makes it easy to forget to register a child element to its parent element, as done in line 18 and 19 of the same listing. The _Java API for KML_ has a _fluent interface_. The term _fluent interface_ was first coined by Eric Evans and Martin Fowler \[FOW08\]. An API with only constructors, setters, and getters is easy to write and often hard to use. An API using a fluent interface is an API designed to be less verbose, more readable, and - as the name implies - to flow. The basic idea of the fluent interface is that each {{set}}-method of the class returns itself instead of {{void}}. This allows method chaining, as the class itself is returned after each method invocation. Each class of _JAK_ provides a {{with}}-method for each defined private field. For example, a {{Placemark}} has a {{<name>}} that can be set with this fluent method: {{public Placemark withName(String name)}}. After the name is set, the method returns a reference to the current placemark object ({{return this}}). Probably the best way to describe it is to provide a further example: {anchor:listing1} {code:title=Listing 1: An example of _JAK_'s fluent style. Each method returns a reference to the placemark object. There is no need to invoke each method explicitly on the placemark object anymore. The code is less verbose.} Placemark placemark = KmlFactory.createPlacemark(); placemark.withName("Java User Group Hessen - JUGH!") .withVisibility(true) .withOpen(false) .withDescription("die Java User Group Hessen") .withStyleUrl("styles.kml#jugh_style"); {code} One problem shown in [KML in the Java world#Listing 4|jak:KML in the Java world#listing4] was that child elements needed to be explicitly bound to their parent element. The standard procedure is: # Create the parent element or get its reference, e.g. a {{placemark}} (line 04). # Create the child element, e.g. {{point}} (line 12). # Register the child element at the parent element, e.g. {{placemark.setGeometry(point)}} (line 18). This involves many points at which errors (at least three) can be made. To reduce this repetitive and error prone boiler code, _JAK_ offers convenience methods prefixed with {{createAndAdd}} and {{createAndSet}}. As the name implies, it creates a new element and sets (or adds) it to its parent. They reduce the three steps or function calls into one and return the created element. This makes it easy to process it in a fluent style. As seen on [KML in the Java world#Figure 3|jak:KML in the Java world#figure3], every {{Placemark}} contains a {{Geometry}} element. {{Geometry}} is an abstract element with several children inheriting from ([KML in the Java world#Figure 1|jak:KML in the Java world#figure1]). The next figure focuses on the children derived from {{Geometry}}: {anchor:figure1} !Figure421_abstract_geometry.png! h6. Figure 1: An extract of [KML in the Java world#Figure 1|jak:KML in the Java world#figure1] concentrating on the geometry element and its children. For each child of the class, {{Geometry}} a {{createAndSet}}-method is created in the class that contains this element: {anchor:figure2} !Figure422_extract_of_placemark.png! h6. Figure 2: An extract of the class placemark showing some of its createAndSet methods. [Figure 2|#figure2] shows an extract of the {{createAndSet}} methods offered by the class {{Placemark}}. It offers seven convenience methods to {{createAndSet}} a concrete type derived from {{Geometry}} class. Whenever an element is able to contain zero or more elements of the same (abstract) type, the API reflects this circumstance with a slightly different naming convention. A {{createAndAdd}} method is offered instead. {{Placemark}} offers many other convenience methods to {{createAndSet}} or to {{createAndAdd}} elements that can be contained in it. There is one for each complex element that is shown in [KML in the Java world#Figure 3|jak:KML in the Java world#figure3]. In the case of an abstract element, one method for each child of the abstract element is offered by _JAK_. The code of the {{createAndSet}} and {{createAndAdd}} methods is simple and helps clients of the API to reduce a lot of error prone boiler code: {anchor:listing2} {code:title=Listing 2: Shows an example for a createAndSet method (left side) and a createAndAdd method (right side) both contained in Placemark.} public Point createAndSetPoint() { Point newValue = new Point(); this.setGeometry(newValue); return newValue; } public Style createAndAddStyle() { Style newValue = new Style(); this.getStyleSelector().add(newValue); return newValue; } {code} A similar convenience method with the prefix {{addTo}} is created for every simple element that is able to contain zero or more elements of the same type: {anchor:listing3} {code:title=Listing 3: The addTo method exemplary for the Point class.} class Point { public Point addToCoordinates(final String coordinates) { this.getCoordinates().add(new Coordinate(coordinates)); return this; } ... {code} The next listing shows the fluent style and all convenience methods offered by the _Java API for KML_. It is the counterpart to [KML in the Java world#Listing 4|jak:KML in the Java world#listing4]: {anchor:listing4} {code:title=Listing 4: Utilizes the fluent and convenience methods provided by _JAK_. Compared to KML in the Java world # Listing 4 the code is less verbose and error-prone.} Kml kml = KmlFactory.createKml(); kml.createAndSetPlacemark() .withName("Java User Group Hessen - JUGH!") .withVisibility(true) .withOpen(false) .withDescription("die Java User Group Hessen") .withStyleUrl("styles.kml#jugh_style") .createAndSetPoint() .withExtrude(false) .withAltitudeMode(AltitudeMode.CLAMP_TO_GROUND) .addToCoordinates("9.444652669565212,51.30473589438118,0"); kml.marshal(System.out); {code} The naming conventions of the fluent and convenience methods presented here are applied throughout the whole _Java API for KML_. Once understood, they aid in writing code that is less verbose and easier to read. h6. Bibliography | \[FOW08\] | MARTIN FOWLER; Fluent Interfaces; http://www.martinfowler.com/bliki/FluentInterface.html | {column} {column:width=1%} {column} {column:width=29%} {livesearch:id=1|spaceKey=jak} [Java API for KML|Home] | [@Google|http://code.google.com/p/javaapiforkml/] {pagetree} {column} {section}
|