A common feature we have is a report be available available in multiple formats. For example, a pricing report will be available as an Excel spreadsheet for the marketing team to be able to tweak the numbers, as a PDF report to look nice for external customers, and as ASCII text for emailing/SMS-ing out the sales staff.

We accomplish this by decoupling the creation of the output with the report using an interface like

public interface DocumentMaker{
    void makeSectionHeader( String s );
    void makeParagraph( String s );
    void makeFootnote( String s );
    ...
    String make();
}

et cetera. The report logic itself then calls these methods without knowing what the final format of the report it will be.

We end up referring to this pattern as the "builder pattern" (and often use that as our naming) but it does not feel like that is an appropriate application of the pattern. The builder pattern is described as:

Instead of using numerous constructors, the builder pattern uses another object, a builder, that receives each initialization parameter step by step and then returns the resulting constructed object at once.

However, we aren't really interested in the object returned, and often all variations return the same type (eg. String).

It actually, seems closer to the strategy pattern which is described as:

The strategy pattern defines a family of algorithms, encapsulates each algorithm, and makes the algorithms interchangeable within that family. Strategy lets the algorithm vary independently from clients that use it

Which sounds more like we are doing.

Although a colleague suggests that they are abstract factories:

The client doesn't know (or care) which concrete objects it gets from each of these internal factories, since it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from their general usage and relies on object composition, as object creation is implemented in methods exposed in the factory interface.

So, is what we are doing appropriate to call the "builder pattern"? If not, is there a more appropriate pattern to call it?

  • You say that you aren't interested in the object returned, and the return value is often the same type, String, but you know as well as I do that a CSV string is very different from a PDF string is very different from an ASCII String. Thinking about the way you invoke this pattern, it's pretty clear it's a builder. – Christian Carter Nov 1 '15 at 7:04
  • @ChristianCarter there is no further interaction with the object besides writing it to disk. The fact that if the final step of the pattern was to pass in a file name and it wrote to the disk itself, the overall program would be mostly unchanged means that it really doesn't fit the description of "builder pattern is a replacement for a constructor" theme. I've now come to think of it as a fringe case of builder, but I disagree that it's "pretty clear". You'd never overloading the constructor for a string to build the output which would lead to the "telescoping constructor" anti-pattern. – ArtB Nov 1 '15 at 22:32

Your class is definitely a Builder. I would change some names to be more consistent with other implementations of this pattern.

public interface DocumentBuilder {
  void addSectionHeader(String s);
  void addParagraph(String s);
  void addFootnote(String s);
  ...
  String build();
}

Factories and strategies (typically) accomplish a task within single method invocation.

  • The old 'make'-prefixed method names threw me off so much that I didn't think it was a builder. With the 'add'-prefix, it's now obvious to me that it's a builder. – Filip Haglund Oct 26 '15 at 21:07
  • @FilipHaglund It is intentional to not be suggestive of one pattern or another. – ArtB Oct 27 '15 at 2:16

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.