Tuesday, 2 August 2011

Using generics with a fluent API

I've recently worked on an integration project requiring a message API.  It was to be responsible for building messages of various types to be sent on a variety of transports. Each message had numerous parameters but some were only used in particular contexts. This meant that frequently you'd get constructors where some of those parameters had to be set to null to indicate they were not to be used. This is a code smell. One solution would be to use the refactoring 'Introduce parameter object'. This refactoring is used to group parameters together into immutable classes so those parameters have a common context.  This may alleviate the problem somewhat but in practice I found this resulted in several overloaded constructors each with different combinations of parameter objects. I needed another solution.

I've had some success in the past using fluent API with builders. A fluent interface is implemented by using method chaining to relay the instruction context of a subsequent call. My expectation was to create something like:


Some parameters were common to all message types so it made sense to have these in a base class.

The message base class:


and it's associated builder:


I then subclassed the builder class to create the specialized message types. For brevity most parameters have been omitted.

An example of a specialized message class with inherits all the properties of the base class along with its own parameters.


The builder for this class:


However to get the expected usage of:


I've had to subclass all withXXX methods from the Message base class. In this example, it's not too painful as there's only a couple of common parameters but more realistically I could have numerous parameters which means for each specialized subclass I need to override those methods. This approach quickly becomes unwieldy and a maintenance headache. To make sure that method chain returns the correct type I've had to resort to calling the super method and then return the correct type i.e this. Not very good.What I needed was for each subclass to inherit the super class methods implicitly but with the proviso that they return the actual type not the super type.

A solution is to use Self Bound GenericTypes.  Angelika Langer gives a good explanation which she calls the getThis() trick.

The base MessageBuilder class has been changed to use self bound generic types. So for example, instead of hardwiring withId() to return the type of the builder that defines it,  a type parameter B is introduced and  withId() returns B via the abstract self() method. This self method implemented in the subclass to return the concrete type rather than the base type of the builder.  The self-referential definition MessageBuilder<B extends MessageBuilder<B>>  allows the return type of the inherited withId() in RequestBuilder to be RequestBuilder rather than MessageBuilder.



Now all the subclass has to do, in addition to its own fluent methods, is to provide an implementation of the self() method. Job done.


In this way, subclasses for builders only need be concerned with providing fluent methods for the parameters pertinent to that class. They will automatically inherit fluent methods from the super class so no overriding is required and the intent of the class is clearer.  I can build up that message's fluent methods to set the parameters I actually need for that particular context without resorting to long unwieldy parameter lists. Again the intent is clearer. Result !

Thanks to a bit of tinkering, this solution seems elegant and understandable now but as usual with generics it'll be mostly incomprehensible tomorrow :).

Links

Monday, 1 August 2011

A comparison of FDD and Scrum


FDD and Scrum are two examples of agile development methodologies. Agile development tries to avoid the main weakness of "waterfall" by doing iterative development. Each iteration is meant to be short (1-2 weeks) and includes all of the following steps.
  • Gathering user requirements
  • Design and documentation
  • Development
  • Testing
  • Deployment
This guarantees that design errors are discovered at early stages of development. I've had experience on working on projects using both methodologies and it was interesting to compare the salient features of both approaches.  Before the comparison, a short overview of each practice is given.

Feature Driven Development
Feature Driven Development, FDD  is an agile software development methodology by Jeff De Luca and Peter Coad.  It has more formal requirements and steps than Scrum from a development perspective.

 
















FDD consists of five high level activities:
  • Develop an overall domain mode
    • FDD advocates light modelling up front to understand the shape and scope of the application.
  • Build a list of features
    • Team builds a feature list.  Each feature represents 1-10 days worth of effort.  
    • A feature is a small piece of client-valued function expressed in the form: <action> <result> <object> i.e. Calculate the total of a sale
  • Plan by feature
    • Features are then assigned to iterative release cycles.
    • Developers are also assigned to own particular classes identified in the domain model by a chief programmer.
  • Design By Feature (DBF)
    • Feature teams are assigned to a set of features and proceed to the design in detail i.e. sequence diagrams 
  • Build By Feature (BBF)
    • Those teams then carry out the code development and testing of those features.
    • When chief programmer is satisfied then completed features are promoted to the main build.
FDD utilizes chief programmer, inspections, and class ownership. The chief programmers function as team leaders, mentors, and reviewers. While the term chief programmer may suggest micro-management and control, FDD teams stress the collaboration and knowledge sharing roles.


Progress and can be tracked and reported with accuracy by assigning a percentage weighting to each step in a DBF/BBF iteration The chief programmers indicate when each step has been completed for each feature they're developing. This enables a view on how much of a particular feature has been completed.  The cycle repeats itself either by refinement of the original domain model and subsequent activities or until all the features in the list have been built.

Scrum

Scrum is an
iterative, incremental framework for project management often seen in agile software development, a type of software engineering. Essentially Scrum boils down to the following points (from Scrum Alliance):