Working With Design Patterns: Abstract Factory
Listing 6: HtmlCatalogReportFactory.
import domain.*; public class HtmlCatalogReportFactory extends CatalogReportFactory { public HtmlCatalogReportFactory(Catalog catalog) { super(catalog); } @Override protected ReportComponent createDetailRecord(Material material) { return new HtmlReportDetailRecord(material); } @Override protected ReportComponent createReportHeader() { return new HtmlReportHeader(); } @Override protected ReportComponent createSummary() { return new HtmlReportSummary(); } }
Listing 7: MaterialSorter.
import java.util.*; import domain.*; public class MaterialSorter implements Comparator<Material> { private List<Material> materialsCopy; public MaterialSorter(List<Material> materials) { materialsCopy = new ArrayList<Material>(materials); } @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()); } public List<Material> sort() { Collections.sort(materialsCopy, this); return materialsCopy; } }
Each creation method returns a ReportComponent:
public interface ReportComponent { void appendTo(Report report); }
The job of a ReportComponent is to produce some amount of text that can be appended to a Report. A Report is a simple helper class—basically a wrapper for StringBuilder—that adds a few useful elements to help simplify client code:
public class Report { static final String EOL = System.getProperty("line.separator"); private StringBuilder buffer = new StringBuilder(); @Override public String toString() { return buffer.toString(); } public void appendLine(String text) { buffer.append(text); buffer.append(EOL); } }
Each of the HTML report component factories is, for the most part, a trivial one-line method. The three implementations, plus the Html utility class, appear in Listing 8.
Listing 8: HTML factory components.
// Html.java public class Html { public static String td(String element) { return tag(element, "td"); } public static String th(String element) { return tag(element, "th"); } public static String tag(String element, String tag) { return String.format("<%s>%s</%s>", tag, element, tag); } } // HtmlReportHeader.java import static abstractfactory.Html.*; public class HtmlReportHeader implements ReportComponent { @Override public void appendTo(Report report) { report.appendLine("<body>"); report.appendLine("<table>"); report.appendLine(String.format("<tr>%s%s%s%s</tr>", th("Title"), th("Auth/Dir"), th("Classification"), th("Year"))); } } // HtmlReportDetailRecord.java import static abstractfactory.Html.*; import domain.*; public class HtmlReportDetailRecord implements ReportComponent { private final Material material; public HtmlReportDetailRecord(Material material) { this.material = material; } @Override public void appendTo(Report report) { report.appendLine(String.format("<tr>%s%s%s%s</tr>", td(material.getTitle()), td(material .getAuthor()), td(material.getClassification()), td(material.getYear()))); } } // HtmlReportSummary.java public class HtmlReportSummary implements ReportComponent { @Override public void appendTo(Report report) { report.appendLine("</table>"); report.appendLine("</body>"); } }
Page 3 of 4
This article was originally published on September 4, 2008