November 27, 2014
Hot Topics:

Working With Design Patterns: Builder

  • April 21, 2008
  • By Jeff Langr
  • Send Email »
  • More Articles »

Listing 3: The director.

import java.util.*;

public class CatalogReportDirector {
   private final Catalog catalog;

   public CatalogReportDirector(Catalog catalog) {
      this.catalog = catalog;
   }

   public String generate(CatalogReportBuilder builder) {
      return createReport(builder, sort(catalog));
   }

   private List<Material> sort(Catalog catalog) {
      List<Material> catalogCopy =
         new ArrayList<Material>(catalog.materials());
      Collections.sort(catalogCopy, new Comparator<Material>() {
         @Override
         public int compare(Material material1,
                            Material material2) {
            if (material1.getClass() == material2.getClass()) {
               if (material1.getTitle().
                  equals(material2.getTitle()))
                  return material1.getAuthor().
                     compareTo(material2.getAuthor());
               return material1.getTitle().
                  compareTo(material2.getTitle());
            }
            return material1.getClass().getName().compareTo(
                  material2.getClass().getName());
         }
      });
      return catalogCopy;
   }

   private String createReport(CatalogReportBuilder builder,
         List<Material> sortedCatalog) {
      builder.generateHeader();
      for (Material material: sortedCatalog)
         builder.generateDetail(material);
      builder.generateSummary();
      return builder.getReport();
   }
}

The fact that the client is responsible for creating and passing a builder object to the director is another nuance of the builder pattern.

So, what do builders look like? Listing 4 shows the structure of a builder, represented as an abstract class. Listing 5 shows the implementation for an HTML builder.

Listing 4: The builder.

public abstract class CatalogReportBuilder {
   static final String EOL = System.getProperty("line.separator");
   private StringBuilder report = new StringBuilder();

   public String getReport() {
      return report.toString();
   }

   abstract public void generateHeader();
   abstract public void generateDetail(Material material);
   abstract public void generateSummary();

   protected void appendLine(String text) {
      report.append(text);
      report.append(EOL);
   }
}

The builder class holds on to a report reference. As portions of the construction algorithm execute, the report fills in. Listing 6 shows what an alternate builder might look like.

Listing 5: An HTML builder.

public class HtmlCatalogBuilder extends CatalogReportBuilder {
   @Override
   public void generateDetail(Material material) {
      appendLine(String.format("<tr>%s%s%s%s</tr>",
            td(material.getTitle()),
            td(material.getAuthor()),
            td(material.getClassification()),
            td(material.getYear())));
   }

   @Override
   public void generateHeader() {
      appendLine("<body>");
      appendLine("<table>");
      appendLine(String.format("<tr>%s%s%s%s</tr>",
            th("Title"),
            th("Auth/Dir"),
            th("Classification"),
            th("Year")));
   }

   @Override
   public void generateSummary() {
      appendLine("</table>");
      appendLine("</body>");
   }

   private String td(String element) {
      return tag(element, "td");
   }

   private String th(String element) {
      return tag(element, "th");
   }

   private String tag(String element, String tag) {
      return String.format("<%s>%s</%s>", tag, element, tag);
   }
}




Page 2 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel