dcsimg
March 31, 2020
Hot Topics:

Working With Design Patterns: Builder

  • 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



This article was originally published on April 21, 2008

Enterprise Development Update

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


Thanks for your registration, follow us on our social networks to keep up-to-date