Builder Pattern
Gamma Categorization: Creational Design PattenSummary: When piecewise object construction is complicated, provide an API for doing it succintly.
Problem examples
App needs to construct multiple type classesThese classes have complicated construction methods
Isolate construction process from application
Solution
Builder Interface or Abstract classCreate Builder classes that implement builder interface for each object type
Director class: uses builder class to create object
Sample Code
Problem: we need to construct a Sales Report, that must be built every day with the sales summary.
Code
So in order to build the report we need an abstract ReportBuilder class, with a simple constructor that initializes the report. The class contains methods for constructing the header, content and footer. The DispatchReport will be implemented for each report type.
public abstract class ReportBuilder
{
protected Report report;
public void CreateReport() => report = new Report();
public void SetHeader(string header) => report.Header = header;
public void AppendContentLine(string contentLine) => report.Content.Add(contentLine);
public void SetFooter(string footer) => report.Footer = footer;
public abstract string DispatchReport();
public void Clear() => report = new Report();
}
The Report object containds a header, multiple content lines and a footer.
As an example, we will implement a text report, that will print the report as a string.
public class Report
{
public string Header { get; set; }
public List<string> Content { get; set; } = new List<string>();
public string Footer { get; set; }
}
As an example, we will implement a text report, that will print the report as a string.
public class TextReportBuilder : ReportBuilder
{
public override string DispatchReport()
{
var hr = "-------------------------";
var sb = new StringBuilder();
sb.AppendLine(hr);
sb.AppendLine(report.Header);
sb.AppendLine(hr);
foreach (var contentLine in report.Content)
{
sb.AppendLine(contentLine);
}
sb.AppendLine(hr);
sb.AppendLine(report.Footer);
sb.AppendLine(hr);
return sb.ToString();
}
}
Usage
var textReportBuilder = new TextReportBuilder();
textReportBuilder.CreateReport();
textReportBuilder.SetHeader($"Daily Report - {DateTime.UtcNow.ToString("dd/MM/yyyy")}");
textReportBuilder.AppendContentLine("14 Hot Meals");
textReportBuilder.AppendContentLine("22 Breakfasts");
textReportBuilder.SetFooter("Copyright - Cafe Shop");
System.Console.WriteLine(textReportBuilder.DispatchReport());
-------------------------
Daily Report - 06/12/2019
-------------------------
14 Hot Meals
22 Breakfasts
-------------------------
Copyright - Cafe Shop
-------------------------
Note: The Builder Patter definition states that you must have a Director object that basicaly encapsulates what we did in the Usage section. It will depend on your context if it makes sense to use a Director class or if you need the flexibility to assemble the report yourself dynamically.
Next, you can proceed to extend the pattern in order chain the build operations using the Fluent Builder Pattern
Comments
Post a Comment